由于项目的需要,博主需要做一个修改密码的功能,项目用到的是laravel框架,但是没想到他里面的Hash::make()跟之前写过的md5()有很大的差别,下面总结一下 ,laravel自带Hash::make加密 规则默认为AES-256-CBC;框架设计为前后端分离,laravel做接口,前端node.js ,ios,Android
这里遇到的坑就是laravel框架中,每次hash的值都是不一致的,跟之前写过的md5不一样,md5是唯一的,但是只要保存进去了,就算hash以后的值是不一样的,但是都是代表一个东西的,比如说,你hash的是111111,就算hash两次的值不一致,但是并不会影响你的代码逻辑的,只要正常判断即可,laravel不愧为排名第一的框架,果然很优雅!!!!
一、iosAES 加密解密
//AES加密
+(NSString*)encodeAESWith:(NSString*)str{
if(!str) {
return@"";
}
NSString* key=AESKey;//密钥
NSData*data=[str dataUsingEncoding:NSUTF8StringEncoding];//待加密字符转为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进行加密
最近在使用Cookies加密保存数据的时候,接触到crypto,使用还算简单,在这里记录一下。
可以在这个GitHub的https://github.com/brix/crypto-js上下载该js,它可以单独引入所需要加密方式的js;也可以引入一个crypto-js.js 这个文件,它相当于引入了所有的加密方式,我使用的就是后者一次引入所有的加密文件,这个文件也不是很大,还可以接受。
因为我的需求是加密可逆,具有一定的安全性(对安全性要求并不是特别高),所以使用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加密 规则默认为AES-256-CBC
数据库中的密码使用Hash加密保存
$param['mobile_phone'],
'password' => Hash::make('000000'),
'sex' => $param['gender'],
'phone' => $param['mobile_phone']
];
$userResult = UserModel::m_addUser($data);
}
}
七、laravel 用Hash::check解密
控制器层
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'=>'登录失败']);
}
}
}
业务处理Service层
400,
'msg' => '用户名或密码不正确'
];
}else{
return [
'code' => 200,
'msg' => '验证成功'
];
}
}
}
Model层
where('is_delete', 0)->first();
return object_to_array($user);
}
}
==这里遇到的坑就是laravel框架中,每次hash的值都是不一致的,跟之前写过的md5不一样,md5是唯一的,但是只要保存进去了,就算hash以后的值是不一样的,但是都是代表一个东西的,比如说,你hash的是111111,就算hash两次的值不一致,但是并不会影响你的代码逻辑的,只要正常判断即可,laravel不愧为排名第一的框架,果然很优雅!!!!==