PHP中怎么实现aes加密解密

发布时间:2021-06-29 17:08:14 作者:Leah
来源:亿速云 阅读:450

PHP中怎么实现aes加密解密,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

aes加密解密过程

用户数据应经过加密再传输,此文档为aes128加密(cbc模式)的说明 摘要算法为SHA-512

加密:

生成16位iv向量,使用该iv以及密钥加密原文

将加密后的真实密文与iv拼接: iv+真实密文

将与iv拼接后的密文用SHA-512 HMAC生成摘要信息(128位),与密文拼接: HMAC+base64后的密文,得到最终的密文

解密:

分离出hmac与密文,可以自行进行摘要检测,可以防止时序攻击.

得到拼接了iv的原文.分离出iv以及真实原文

使用密钥以及iv进行解码,得到原文

加密举例 php版本

        /*****加密过程*****/

        $str = "Hello World";

        //1.使用16位密钥

        $key = '12345678901234ab';

        //2.生成16位iv 算法自定,示例中直接指定

        //$iv = openssl_random_pseudo_bytes(16); //12345678ss1234ab

        $iv="12345678ss1234ab";

        //3.加密      IvdA7oP8BInWa5shY+LCyQ==

        $secert_str = openssl_encrypt($str, 'AES-128-CBC', $key, 0, $iv);

        $secert_str = $iv . $secert_str;        //4.将iv与密文拼接    12345678ss1234abIvdA7oP8BInWa5shY+LCyQ==

        //5.base64_encode   考虑语言兼容性问题,该步骤取消

        //6.用SHA-512生成摘要 128位16进制   3b2106c05b46b603969c2b1bc7503c8233d209dcd204b098b33ba704507315480e03e499e0082e8842b60baa01f522d7c0342d75196d18d3514d37c58e31d733

        $hmac = hash_hmac('sha512', $secert_str, $key, false);

        //7.拼接摘要,得到密文

        $secert_str = $hmac . $secert_str;

        return urlencode($secert_str);

解密举例

$str=rawurldecode($str);

$len = mb_strlen($secert_str);

$ori_hmac = substr($secert_str, 0, 128);

$data = substr($secert_str, 128, $len);

//2.验证摘要

$local_hmac = hash_hmac('sha512', $data, $key, false);

$diff = 0;

for ($i = 0; $i < 128; $i++) {

   $diff |= ord($ori_hmac[$i]) ^ ord($local_hmac[$i]);

}

if ($diff !== 0) {

   return FALSE;

}

//3.分离iv

$len = mb_strlen($data);

$iv = substr($data, 0, 16);

$data = substr($data, 16, $len);

//4.解密,获得原文

$data = openssl_decrypt($data, 'AES-128-CBC', $key, 0, $iv);

java加解密类

package main;

import javax.crypto.Cipher;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

import javax.crypto.Mac;

import org.apache.commons.codec.binary.Base64;

import org.bouncycastle.util.encoders.Hex;

public class AESUtil {

    /**

     * aes/128/cbc加密

     * @param sSrc  明文

     * @param sKey  密钥

     * @param sIv   向量

     * @return

     * @throws Exception

     */

    public static String Encrypt(String sSrc, String sKey, String sIv) throws Exception {

        if (sKey == null) {

            System.out.print("Key为空null");

            return null;

        }

        // 判断Key是否为16位

        if (sKey.length() != 16) {

            System.out.print("Key长度不是16位");

            return null;

        }

        //1.加密

        byte[] raw = sKey.getBytes();

        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//aes-cbc-pkcs5(pkcs5与pkcs7通用)

        IvParameterSpec iv = new IvParameterSpec(sIv.getBytes());//使用CBC模式,需要一个向量iv,可增加加密算法的强度

        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

        byte[] encrypted = cipher.doFinal(sSrc.getBytes("UTF-8"));

        String encryptedString = new String(Base64.encodeBase64(encrypted));

        //2.拼接iv

        encryptedString = sIv + encryptedString;

        //3.sha512

        String hmac = encodeHmacSHA512(encryptedString, sKey);

        //4.拼接摘要

        encryptedString = hmac+encryptedString;

        //5.urlencode

        encryptedString = URLEncoder.encode(encryptedString);

        return encryptedString;

    }

    // 解密

    /**

     *

     * @param sSrc  密文

     * @param sKey  密钥

     * @return

     * @throws Exception

     */

    public static String Decrypt(String sSrc, String sKey) throws Exception {

        try{

            //0.urldecode

            sSrc=URLDecoder.decode(sSrc);

            //1.分离摘要

            System.out.println(sSrc);

            String hmac=sSrc.substring(0,128);

            String data=sSrc.substring(128,sSrc.length());

            //2.验证摘要

            //3.分离iv

            String sIv=data.substring(0,16);

            String str=data.substring(16,data.length());

            //4.解密

            byte[] raw = sKey.getBytes("UTF-8");

            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

            IvParameterSpec iv = new IvParameterSpec(sIv.getBytes());

            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

            byte[] encrypted1 = Base64.decodeBase64(str.getBytes());

            try {

                byte[] original = cipher.doFinal(encrypted1);

                String originalString = new String(original);

                return originalString;

            } catch (Exception e) {

                System.out.println(e.toString());

                return null;

            }

        }catch (Exception ex){

            System.out.println(ex.toString());

            return null;

        }

    }

    /**

     * HmacSHA512消息摘要

     *

     * @param data 待做摘要处理的数据

     * @param key  密钥

     * @return

     */

    public static String encodeHmacSHA512(String data, String key) throws Exception {

        byte[] bytesKey = key.getBytes();

        SecretKeySpec secretKey = new SecretKeySpec(bytesKey, "HmacSHA512");

        Mac mac = Mac.getInstance(secretKey.getAlgorithm());

        mac.init(secretKey);

        final byte[] macData = mac.doFinal(data.getBytes());

        byte[] hex = new Hex().encode(macData);

        String result = new String(hex, "ISO-8859-1");

        return result;

    }

}

java实例

import main.AESUtil;

public class Main {

    public static void main(String[] args) {

        //key

        String cKey = "12345678901234ab";

        // 需要加密的字串

        String cSrc = "Hello World";

        //iv 16位  算法自定 实例中直接指定

        String sIv = "12345678ss1234ab";

        String enString;

        String deString;

        try {

            enString = AESUtil.Encrypt(cSrc, cKey, sIv);

            System.out.println("加密后的字串是:" + enString);

            deString = AESUtil.Decrypt("3b2106c05b46b603969c2b1bc7503c8233d209dcd204b098b33ba704507315480e03e499e0082e8842b60baa01f522d7c0342d75196d18d3514d37c58e31d73312345678ss1234abIvdA7oP8BInWa5shY+LCyQ==", cKey);

            System.out.println("解密后的字串是:" + deString);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

关于PHP中怎么实现aes加密解密问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

推荐阅读:
  1. php aes加密解密类(兼容php5、php7)
  2. Python如何实现aes加密解密

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

php

上一篇:PHP中怎么遍历文件

下一篇:PHP中怎么利用多进程处理任务

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》