laravel 账号密码加密修改设计,crypt加密和hash加密总结,适用前后端分离,ios,安卓

由于项目的需要,博主需要做一个修改密码的功能,项目用到的是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不愧为排名第一的框架,果然很优雅!!!!==

你可能感兴趣的:(laravel 账号密码加密修改设计,crypt加密和hash加密总结,适用前后端分离,ios,安卓)