由于項(xiàng)目的需要,博主需要做一個修改密碼的功能腔长,項(xiàng)目用到的是laravel框架袭祟,但是沒想到他里面的Hash::make()跟之前寫過的md5()有很大的差別,下面總結(jié)一下 ,laravel自帶Hash::make加密 規(guī)則默認(rèn)為AES-256-CBC捞附;框架設(shè)計(jì)為前后端分離巾乳,laravel做接口,前端node.js 鸟召,ios胆绊,Android
這里遇到的坑就是laravel框架中,每次hash的值都是不一致的欧募,跟之前寫過的md5不一樣压状,md5是唯一的,但是只要保存進(jìn)去了,就算hash以后的值是不一樣的种冬,但是都是代表一個東西的镣丑,比如說,你hash的是111111娱两,就算hash兩次的值不一致莺匠,但是并不會影響你的代碼邏輯的,只要正常判斷即可十兢,laravel不愧為排名第一的框架趣竣,果然很優(yōu)雅!:滴铩RB啤!
一宵呛、iosAES 加密解密
//AES加密
+(NSString*)encodeAESWith:(NSString*)str{
if(!str) {
return@"";
}
NSString* key=AESKey;//密鑰
NSData*data=[str dataUsingEncoding:NSUTF8StringEncoding];//待加密字符轉(zhuǎn)為NSData型
charkeyPtr[kKeySize+1];
memset(keyPtr,0,sizeof(keyPtr));
[keygetCString:keyPtrmaxLength:sizeof(keyPtr)encoding:NSUTF8StringEncoding];
NSUIntegerdataLength = [datalength];
size_tbufferSize = dataLength +kCCBlockSizeAES128;
void*buffer =malloc(bufferSize);
size_tnumBytesCrypted =0;
NSData*initVector = [kInitVectordataUsingEncoding:NSUTF8StringEncoding];
CCCryptorStatuscryptStatus =CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr,
kCCBlockSizeAES128,
initVector.bytes,
[databytes],
dataLength,
buffer,
bufferSize,
&numBytesCrypted);
if(cryptStatus ==kCCSuccess) {
NSData*resultData=[NSDatadataWithBytesNoCopy:bufferlength:numBytesCrypted];
NSString*result = [resultDatabase64EncodedStringWithOptions:0];
returnresult;
}
free(buffer);
return@"";
}
//AES解密
+ (NSString*)decodeAESString:(NSString*)aesEncodedString{
if(!aesEncodedString){
return@"";
}
NSData*contentData = [[NSDataalloc]initWithBase64EncodedString:aesEncodedStringoptions:NSDataBase64DecodingIgnoreUnknownCharacters];
NSUIntegerdataLength = contentData.length;
charkeyPtr[kKeySize+1];
memset(keyPtr,0,sizeof(keyPtr));
[AESKeygetCString:keyPtrmaxLength:sizeof(keyPtr)encoding:NSUTF8StringEncoding];
size_tdecryptSize = dataLength +kCCBlockSizeAES128;
void*decryptedBytes =malloc(decryptSize);
size_tactualOutSize =0;
NSData*initVector = [kInitVectordataUsingEncoding:NSUTF8StringEncoding];
CCCryptorStatuscryptStatus =CCCrypt(kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr,
kKeySize,
initVector.bytes,
contentData.bytes,
dataLength,
decryptedBytes,
decryptSize,
&actualOutSize);
if(cryptStatus ==kCCSuccess) {
NSData*dataTemp = [NSDatadataWithBytesNoCopy:decryptedByteslength:actualOutSize];
NSString*str = [[NSStringalloc]initWithData:dataTempencoding:NSUTF8StringEncoding];
returnstr;
}
free(decryptedBytes);
return@"";
}
二单匣、安卓/java加密 解密
package com.sdjn.quzg.utils.str;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class EncryptorUtils {
public final static String KEYAES = "DJTggiIeOBu3blSX";
public final static String IVAES = "2oFtRtKzfnkxLB18";
public static String encrypt(String key, String initVector, String value) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
System.out.println("encrypted string: " + Base64.getEncoder().encodeToString(encrypted));
return Base64.getEncoder().encodeToString(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String decrypt(String key, String initVector, String encrypted) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(Base64.getDecoder().decode(encrypted));
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String zgPwd(String pwd) {
return encrypt(KEYAES, IVAES, pwd);
}
}
三、前端使用crypto.js進(jìn)行加密
最近在使用Cookies加密保存數(shù)據(jù)的時候烤蜕,接觸到crypto封孙,使用還算簡單,在這里記錄一下讽营。
可以在這個GitHub的https://github.com/brix/crypto-js上下載該js虎忌,它可以單獨(dú)引入所需要加密方式的js;也可以引入一個crypto-js.js 這個文件橱鹏,它相當(dāng)于引入了所有的加密方式膜蠢,我使用的就是后者一次引入所有的加密文件,這個文件也不是很大莉兰,還可以接受挑围。
因?yàn)槲业男枨笫羌用芸赡妫哂幸欢ǖ陌踩?對安全性要求并不是特別高)糖荒,所以使用DES或AES即可杉辙,我用的是AES:
function getAesString(data,key,iv){//加密
var key = CryptoJS.enc.Utf8.parse(key);
var iv = CryptoJS.enc.Utf8.parse(iv);
var encrypted =CryptoJS.AES.encrypt(data,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return encrypted.toString(); //返回的是base64格式的密文
}
function getDAesString(encrypted,key,iv){//解密
var key = CryptoJS.enc.Utf8.parse(key);
var iv = CryptoJS.enc.Utf8.parse(iv);
var decrypted =CryptoJS.AES.decrypt(encrypted,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
function getAES(data){ //加密
var key = 'DJTggiIeOBu3blSX'; //密鑰 可以修改,自定義
var iv = '2oFtRtKzfnkxLB18'; //偏移量 可以修改捶朵,自定義
var encrypted =getAesString(data,key,iv); //密文
var encrypted1 =CryptoJS.enc.Utf8.parse(encrypted);
return encrypted;
}
function getDAes(data){//解密
var key = 'DJTggiIeOBu3blSX'; //密鑰 可以修改蜘矢,自定義
var iv = '2oFtRtKzfnkxLB18'; //偏移量 可以修改,自定義
var decryptedStr =getDAesString(data,key,iv);
return decryptedStr;
}
key和iv我們都可以更換综看,但是需要保證的是加解密的key和iv保持一致
四品腹、PHP端加密方法,放在PHP laravel Funtions.php 中
/**
* encode_crypt 加密固定key與iv偏移量
* @author storm_fu
* @date 2019/09/05
* @param $encrypt
* @return int|string
*/
function encode_crypt($encrypt)
{
$key = ENV('CRYPT_KEY');//加密鑰匙 env文件中添加: CRYPT_KEY=DJTggiIeOBu3blSX (可以修改红碑,自定義)
$iv = ENV('CRYPT_IV');//偏移量 env文件中添加: CRYPT_IV=2oFtRtKzfnkxLB18 (可以修改舞吭,自定義)
// 加密
$encode = base64_encode(openssl_encrypt($encrypt,"AES-128-CBC",$key,true,$iv));
if($encode){
return $encode;
}else{
return false;
}
}
五、PHP端解密方法 ,放在PHP laravel Funtions.php 中
/**
* decode_crypt解密固定key與iv偏移量
* @author storm_fu
* @date 2019/09/05
* @param $encrypt
* @return int|string
*/
function decode_crypt($encrypt)
{
$key = ENV('CRYPT_KEY');//解密鑰匙 env文件中添加: CRYPT_KEY=DJTggiIeOBu3blSX (可以更改)
$encrypt = base64_decode($encrypt);
$iv = ENV('CRYPT_IV');//偏移量 env文件中添加: CRYPT_IV=2oFtRtKzfnkxLB18 (可以更改)
$decrypt = openssl_decrypt($encrypt, 'AES-128-CBC', $key, true, $iv);
if($decrypt){
return $decrypt;
}else{
return false;
}
}
六羡鸥、laravel自帶Hash::make加密 規(guī)則默認(rèn)為AES-256-CBC
數(shù)據(jù)庫中的密碼使用Hash加密保存
<?php
namespace App\Service\Admin;
use App\Models\Admin\UserModel;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash; //需要引入
class UserService
{
public static function s_add($param)
{
$data = [
'username' => $param['mobile_phone'],
'password' => Hash::make('000000'),
'sex' => $param['gender'],
'phone' => $param['mobile_phone']
];
$userResult = UserModel::m_addUser($data);
}
}
七蔑穴、laravel 用Hash::check解密
控制器層
<?php
namespace App\Http\Controllers\Admin;
use App\Service\Admin\UserService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AuthController extends BaseController
{
/**
* 登錄
* @author storm_fu
* @param \Illuminate\Http\Request;
* @return \Illuminate\Http\Response;
*/
public function login(Request $request)
{
try {
$param=$request->input();
$param['username'] = $request->input('username','');
$param['password'] = $request->input('password','');
$response=UserService::getUser($param);
return jsonResponse($response);
} catch (QueryException $queryException) {
return jsonResponse(['code'=>400,'msg'=>'登錄失敗']);
}
}
}
業(yè)務(wù)處理Service層
<?php
namespace App\Service\Admin;
use App\Models\Admin\UserModel;
use Illuminate\Support\Facades\Hash; //**重點(diǎn)** 需要引入
class UserService
{
public static function getUser($param)
{
$user = UserModel::getUser($param);
//前端解密
$password = decode_crypt($param['password']); //從前端獲取的加密密碼先進(jìn)行解密
//檢查是否和數(shù)據(jù)庫中的密碼一致
if (empty($user) || !Hash::check($password,$user['password'])) {
return [
'code' => 400,
'msg' => '用戶名或密碼不正確'
];
}else{
return [
'code' => 200,
'msg' => '驗(yàn)證成功'
];
}
}
}
Model層
<?php
namespace App\Models\Admin;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class UserModel extends Model
{
protected $table = 'jh_users';
/**
* 獲取用戶信息
* @author storm_fu
* @date 2019/09/05
* @param $param
* @return mixed
*/
public static function getUser($param)
{
$user = self::where('username', $param['username'])->where('is_delete', 0)->first();
return object_to_array($user);
}
}
==這里遇到的坑就是laravel框架中,每次hash的值都是不一致的兄春,跟之前寫過的md5不一樣澎剥,md5是唯一的,但是只要保存進(jìn)去了赶舆,就算hash以后的值是不一樣的,但是都是代表一個東西的祭饭,比如說芜茵,你hash的是111111,就算hash兩次的值不一致倡蝙,但是并不會影響你的代碼邏輯的九串,只要正常判斷即可,laravel不愧為排名第一的框架寺鸥,果然很優(yōu)雅V砼ァ!5ńā烤低!==