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加密保存


<?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'=>'登录失败']);
        }
    }
}

业务处理Service层

<?php

namespace App\Service\Admin;

use App\Models\Admin\UserModel;
use Illuminate\Support\Facades\Hash;     //**重点** 需要引入

class UserService
{
    public static function getUser($param)
    {
        $user = UserModel::getUser($param);     
        //前端解密
        $password = decode_crypt($param['password']);     //从前端获取的加密密码先进行解密
        //检查是否和数据库中的密码一致
        if (empty($user) || !Hash::check($password,$user['password'])) {
            return [
                'code' => 400,
                'msg' => '用户名或密码不正确'
            ];
        }else{
            return [
                'code' => 200,
                'msg' => '验证成功'
            ];
        }
    }
}

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是唯一的,但是只要保存进去了,就算hash以后的值是不一样的,但是都是代表一个东西的,比如说,你hash的是111111,就算hash两次的值不一致,但是并不会影响你的代码逻辑的,只要正常判断即可,laravel不愧为排名第一的框架,果然很优雅!!!!==

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容