精华内容
下载资源
问答
  • 问题在使用 AES CBC 模式加密字符串后,再进行解密解密得到的字符串出现乱码情况,通常都是前几十个字节乱码;复现因为是使用部门 cgiAESEncryptUtil 库,找到问题后,在这里复现不太方便,这里使用 python 进行...

    问题

    在使用 AES CBC 模式加密字符串后,再进行解密,解密得到的字符串出现乱码情况,通常都是前几十个字节乱码;

    复现

    因为是使用部门 cgi AESEncryptUtil 库,找到问题后,在这里复现不太方便,这里使用 python 进行复现,可以方便复现。

    #!/usr/bin/env python

    #coding=utf-8

    from Crypto.Cipher import AES

    PADDING = '\0'

    if __name__ == "__main__":

    pad_it = lambda s: s+(16 - len(s)%16)*PADDING

    key = '0123456789abcdef'

    data = pad_it('luffichen0123456789abcdef')

    aes_util = AES.new(key, AES.MODE_CBC, b'0000000000000000')

    crypt = aes_util.encrypt(data)

    print(base64.b64decode(crypt))

    print(data)

    # 使用同一个 aes_util 会导致乱码

    recovery = aes_util.decrypt(crypt)

    print(recovery)

    输出结果:

    1525170642_62_w409_h55.png

    结论

    在 CBC 模式,同个AES对象,所有之前的加解密会影响下一次加解密(加密解密谁先谁后影响都一样),因为 CBC 是 Block chained 的,加密的时候是串行的,需要依赖上个块的加解密结果,可以理解为它是有记录中间状态的过程,所以下一次加解密使用原来的 AES 对象存在问题;ECB模式则没有这个问题;详细可以看 wiki:https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

    解决方法

    每次加解密都需要重新生成一个 AES 对象。

    展开全文
  • JAVA AES加密解密中文乱码

    千次阅读 2018-04-10 16:11:46
    与客户对接,由客户方提供加密解密工具,从工作及测试加密传输后解密正常,但将项目部署到线上服务器,客户接收数据时出现中文乱码,如闻如下: AES加密时会将被加密数据转换成编码格式的字节数组也就是String....

    与客户对接,由客户方提供加密解密工具,从工作及测试加密传输后解密正常,但将项目部署到线上服务器,客户接收数据时出现中文乱码,如闻如下:
    AES加密时会将被加密数据转换成编码格式的字节数组也就是String.getBytes()方法,当getBytes方法不设置参数时,默认使用本机默认编码格式,改成String.getBytes(“utf-8”)问题解决

    展开全文
  • 最近在项目中遇到aes解密128位ecb模式(在内容和key确定的情况下加密出来的内容是固定不变的),开始java后端的aes解密是把内容加密后的字节数组encode_content直接发送给Java后端,这样导致前端vue中的aes加...

    最近在项目中遇到aes加解密128位ecb模式(在内容和key确定的情况下加密出来的内容是固定不变的),开始java后端的aes加解密是把内容加密后的字节数组encode_content直接发送给Java后端,这样导致前端vue中的aes加解密不能和Java后台互通,原因是前端vue加解密传输的内容是字符串,不能直接传输byte数组,所以无法互通。如果要实现跨平台通用最好不要直接传输字节数组。

          aes加密后的内容输出格式可以是十六进制的字符串也可以是base64加密的字符串。

    通用的后端算法如下,

    public static String enCode(String content, String key) {
            if (key == null || "".equals(key)) {
                logger.info("key为空!");
                return null;
            }
            if (key.length() != 16) {
                logger.info("key长度不是16位!");
                return null;
            }
            try {
                byte[] raw = key.getBytes();  //获得密码的字节数组
                SecretKeySpec skey = new SecretKeySpec(raw, "AES"); //根据密码生成AES密钥
                Cipher cipher = Cipher.getInstance(ALGORITHM);  //根据指定算法ALGORITHM自成密码器
                cipher.init(Cipher.ENCRYPT_MODE, skey); //初始化密码器,第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作,第二个参数为生成的AES密钥
                byte [] byte_content = content.getBytes("utf-8"); //获取加密内容的字节数组(设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码            
                byte [] encode_content = cipher.doFinal(byte_content); //密码器加密数据
                return Base64.encodeBase64String(encode_content); //将加密后的数据转换为字符串返回
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }  
        }

    后端的解密方法:

    public static String deCode(String content, String key) {
            if (key == null || "".equals(key)) {
                logger.info("key为空!");
                return null;
            }
            if (key.length() != 16) {
                logger.info("key长度不是16位!");
                return null;
            }
            try {
                byte[] raw = key.getBytes();  //获得密码的字节数组
                SecretKeySpec skey = new SecretKeySpec(raw, "AES"); //根据密码生成AES密钥
                Cipher cipher = Cipher.getInstance(ALGORITHM);  //根据指定算法ALGORITHM自成密码器
                cipher.init(Cipher.DECRYPT_MODE, skey); //初始化密码器,第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作,第二个参数为生成的AES密钥    
                byte [] encode_content = Base64.decodeBase64(content); //把密文字符串转回密文字节数组
                byte [] byte_content = cipher.doFinal(encode_content); //密码器解密数据
                return new String(byte_content,"utf-8"); //将解密后的数据转换为字符串返回
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }  
        }

    这样的话在vue等js前端也可以和java平台的aes加解密互通;

    前端加密解密实现:引入crypto.js

    /***************************************************** 
    * AES加密 
    * @param content 加密内容 
    * @param key 加密密码,由字母或数字组成 
          此方法使用AES-128-ECB加密模式,key需要为16位 
          加密解密key必须相同,如:abcd1234abcd1234 
    * @return 加密密文 
    ****************************************************/

    function encrypt(content, key){
        var sKey = CryptoJS.enc.Utf8.parse(key);
        var sContent = CryptoJS.enc.Utf8.parse(content);
        var encrypted = CryptoJS.AES.encrypt(sContent, sKey, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
        return encrypted.toString();
    }

    /***************************************************** 
    * AES解密 
    * @param content 加密密文 
    * @param key 加密密码,由字母或数字组成 
          此方法使用AES-128-ECB加密模式,key需要为16位 
          加密解密key必须相同,如:abcd1234abcd1234 
    * @return 解密明文 
    ****************************************************/

    function decrypt(content, key){
        var sKey = CryptoJS.enc.Utf8.parse(key);
        var decrypt = CryptoJS.AES.decrypt(content, sKey, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
        return CryptoJS.enc.Utf8.stringify(decrypt).toString();
    }

     

    注:此方法为AES,128位,ECB模式加密解密。

      前后端只要保持key相同,可以相互加密解密。

    展开全文
  • AES 加密解密工具类 AES加密解密 /** * @program: test * @description: AES 加密解密工具类 * @author: 闲走天涯 * @create: 2021-08-20 15:58 */ public class AESUtil { //秘钥 private static final ...

    AES 加密解密工具类

    RSA非对称加密算法:Java RSA非对称加密算法demo工具类 RSA加密解密.

    AES加密解密
    /**
     * @program: test
     * @description: AES 加密解密工具类
     * @author: 闲走天涯
     * @create: 2021-08-20 15:58
     */
    public class AESUtil {
    
        //秘钥
        private static final String SECRET_KEY = "wdesjqiw123oehs12sn32nv325w6q23vdf9g6h";
        //秘钥位数,限制秘钥长度为 16/32
        private static final Integer DIGIT = 32;
    
        /**
         * 加密
         * 1.构造密钥生成器
         * 2.根据ecnodeRules规则初始化密钥生成器
         * 3.产生密钥
         * 4.创建和初始化密码器
         * 5.内容加密
         * 6.返回字符串
         * @param encodeRules 秘钥
         * @param content 内容
         * @return
         */
        public static String AESEncode(String encodeRules,String content){
            try {
                //1.构造密钥生成器,指定为AES算法,不区分大小写
                KeyGenerator keygen=KeyGenerator.getInstance("AES");
                //2.根据ecnodeRules规则初始化密钥生成器
                //生成一个128位的随机源,根据传入的字节数组
                keygen.init(128, new SecureRandom(encodeRules.getBytes()));
                //3.产生原始对称密钥
                SecretKey original_key=keygen.generateKey();
                //4.获得原始对称密钥的字节数组
                byte [] raw=original_key.getEncoded();
                //5.根据字节数组生成AES密钥
                SecretKey key=new SecretKeySpec(raw, "AES");
                //6.根据指定算法AES自成密码器
                Cipher cipher=Cipher.getInstance("AES");
                //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
                cipher.init(Cipher.ENCRYPT_MODE, key);
                //8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
                byte [] byte_encode=content.getBytes("utf-8");
                //9.根据密码器的初始化方式--加密:将数据加密
                byte [] byte_AES=cipher.doFinal(byte_encode);
                //10.将加密后的数据转换为字符串
                //这里用Base64Encoder中会找不到包
                //解决办法:
                //在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
                String AES_encode=new String(new BASE64Encoder().encode(byte_AES));
                //11.将字符串返回
                return AES_encode;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 加密 第二种方式
         * @param encodeRules 秘钥
         * @param content 内容
         * @return
         */
        public static String AESEncode2(String encodeRules,String content){
            try {
                //拼接秘钥位数16/32
                encodeRules=getKeyByDigit(encodeRules,DIGIT);
                //生成AES密钥
                SecretKey key=new SecretKeySpec(encodeRules.getBytes(), "AES");
                //根据指定算法AES自成密码器
                Cipher cipher=Cipher.getInstance("AES");
                //初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
                cipher.init(Cipher.ENCRYPT_MODE, key);
                //获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
                byte [] byte_encode=content.getBytes("utf-8");
                //根据密码器的初始化方式--加密:将数据加密
                byte [] byte_AES=cipher.doFinal(byte_encode);
                //将加密后的数据转换为字符串
                //这里用Base64Encoder中会找不到包
                //解决办法:
                //在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
                String AES_encode=new String(new BASE64Encoder().encode(byte_AES));
                //将字符串返回
                return AES_encode;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 解密
         * 解密过程:
         * 1.同加密1-4步
         * 2.将加密后的字符串反纺成byte[]数组
         * 3.将加密内容解密
         * @param encodeRules 秘钥
         * @param encodeContent 密文
         * @return
         */
        public static String AESDncode(String encodeRules,String encodeContent){
            try {
                //1.构造密钥生成器,指定为AES算法,不区分大小写
                KeyGenerator keygen=KeyGenerator.getInstance("AES");
                //2.根据ecnodeRules规则初始化密钥生成器
                //生成一个128位的随机源,根据传入的字节数组
                keygen.init(128, new SecureRandom(encodeRules.getBytes()));
                //3.产生原始对称密钥
                SecretKey original_key=keygen.generateKey();
                //4.获得原始对称密钥的字节数组
                byte [] raw=original_key.getEncoded();
                //5.根据字节数组生成AES密钥
                SecretKey key=new SecretKeySpec(raw, "AES");
                //6.根据指定算法AES自成密码器
                Cipher cipher=Cipher.getInstance("AES");
                //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
                cipher.init(Cipher.DECRYPT_MODE, key);
                //8.将加密并编码后的内容解码成字节数组
                byte [] byte_content= new BASE64Decoder().decodeBuffer(encodeContent);
                //解密
                byte [] byte_decode=cipher.doFinal(byte_content);
                //输出字符串
                String AES_decode=new String(byte_decode,"utf-8");
                return AES_decode;
            } catch (Exception e) {
                e.printStackTrace();
            }
            //如果有错就返加nulll
            return null;
        }
    
        /**
         * 解密 第二种方式
         * @param encodeRules 秘钥
         * @param encodeContent 密文
         * @return
         */
        public static String AESDncode2(String encodeRules,String encodeContent){
            try {
                //拼接秘钥位数16/32
                encodeRules=getKeyByDigit(encodeRules,DIGIT);
                SecretKey key=new SecretKeySpec(encodeRules.getBytes(), "AES");
                //根据指定算法AES自成密码器
                Cipher cipher=Cipher.getInstance("AES");
                //初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
                cipher.init(Cipher.DECRYPT_MODE, key);
                //将加密并编码后的内容解码成字节数组
                byte [] byte_content= new BASE64Decoder().decodeBuffer(encodeContent);
                //解密
                byte [] byte_decode=cipher.doFinal(byte_content);
                //输出字符串
                String AES_decode=new String(byte_decode,"utf-8");
                return AES_decode;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 控制密钥位数为16/32位
         * @param key
         * @return
         */
        public static String getKeyByDigit(String key,Integer digit){
            StringBuffer newKey = new StringBuffer();
            if(key.length()>digit){
                newKey.append(key.substring(0,digit));
            }else if(key.length()<digit){
                newKey.append(key);
                for(int i=0;i<digit-key.length();i++){
                    newKey.append("1");
                }
            }else{
                newKey.append(key);
            }
            return newKey.toString();
        }
    
        public static void main(String[] args) {
            String content = "你好,中国";
            //加密
            String encode = AESUtil.AESEncode(SECRET_KEY,content);
            //解密
            String dncode = AESUtil.AESDncode(SECRET_KEY,encode);
            System.out.println("原文:"+content);
            System.out.println("加密后:"+encode);
            System.out.println("解密后:"+dncode);
            System.out.println("秘钥位数:"+SECRET_KEY.length()+",密文位数:"+encode.length());
        }
    }
    
    展开全文
  • 内容:abcdkey:1234567890123456加密后base64:t7ut2nq1afvr9unja0wkwa==function apidatadecrypt($data, $key='') {$data = base64_decode($data);$pad = 16 - (strlen($data) % 16);$paddata = $data ....
  • 这里使用AES128,进行加密,解密 加密示例: /** * * 加密 * * @param sSrc 原字符 * @param sKey 16位字符的key * @return * @throws Exception * @return String * @exception 异常描述 * ...
  • aes解密后,用byte[]进行接收,需要使用new String();进行转换为字符。只需要指定new String()编码格式便可以解决解密乱码问题。 接下来我们看下2块解密时部分代码: 1.将aes得到结果转变为字符,不设置编码格式 ...
  • AES 解密乱码问题

    2017-07-07 11:29:00
    最近在搞文件加密,采用AES加密,目前存在一些问题,描述如下: 需将加密后的文件保存为文本,但是下次再读取文本,解密, 有部分数据解密正确, 但是有部分解密错误, 还有一部分乱码, 这我很不能理解,请大神们...
  •  * 将base 64 code AES解密   * @param encryptStr 待解密的base 64 code   * @param decryptKey 解密密钥   * @return 解密后的string   * @throws Exception   */  public static String...
  • 只需要指定new String()编码格式便可以解决解密乱码问题。 接下来我们看下2块解密时部分代码: 1.将aes得到结果转变为字符,不设置编码格式 new String(aesDecrypt(Base64.decode(ciphertext),Base64.decode(key)...
  • AES解密

    2021-05-04 14:19:24
    一:AES解密
  • AES解密

    2018-01-11 16:08:46
    整理AES解密,字节数组与十六进制字符串的相互转换。public class AES { public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, ...
  • $key = '1234567890123456';$content = 'T7UT2NQ1AFvR9unjA0wKWA==';$desStr = decryptString($content,$key);echo($desStr);function decryptString($str,$key) {$str = base64_decode($str);$str = mcrypt_decr...
  • 使用AES加密解密代码详解 首先,如果是使用nodejs + vue 写的前端, 那么你需要npm 加载一个js文件 npm i crypto-js --save --save-exact npm install crypto-js java代码加密解密类 package ...
  • java AES解密

    2020-11-02 15:52:05
    java AES解密 参考链接:https://blog.csdn.net/weixin_44505962/article/details/101231330 import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; ...
  • AES加密解密

    2020-07-07 15:09:12
    AES加密解密工具类 package com.grid.service.common.util; import lombok.extern.slf4j.Slf4j; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.crypto.*; import javax.crypto....
  • 自己尝试使用aes的cbc模式加密字符串,并解密字符串,并在最后使用OpenSSl自带的获取错误消息函数,获取错误信息,显示在加密和解密的过程中没有报错,但是将最后的明文结果输出,得到的始终是乱码啊。下面为自己写...
  • 根据文章的代码再加上面所说分割字符串,就可以实现使用ue4自带的AES加密解密了,但是这个时候问题又出现了,输入中文的话,输出的结果是乱码的。。。我的解决方法是先把FString转成TArray,再转成Base64后加密。同理...
  • php AES加密解密

    2018-11-14 18:29:06
    最近做个项目,为了保证用户信息的安全,用到了一个AES加密算法,很方便也很实用,可以直接拿去用,具体的加密规则可以自己定义,有需要的可以参考下
  •  因开发需求,需要通过前端js加密传输数据,通过各种度娘搜索最后采用了AES方式,但是发现有的是有代码没文件,有的是测试解密出现乱码,现在将自己最后采用的方式总结一下。  首先就是关于所引用的AES加密解密包...
  • Golang AES解密

    千次阅读 2019-04-18 20:35:45
    利用Go提供的AES解密与Base64编解码包,我们可以轻松地实现AES的加解密。实现之前,首先了解一下AES的一个常识点。 (1)AES有5种加密模式,分别是: (a)电码本模式(Electronic Codebook Book,ECB); (b...
  • 只需要指定new String()编码格式便可以解决解密乱码问题。 接下来我们看下2块解密时部分代码: 1.将aes得到结果转变为字符,不设置编码格式 new String(aesDecrypt(Base64.decode(ciphertext),Base64.decode(key))) ...
  • 注意AES解密与php对接知道是hex解密还是base64解密,如果是base64解密需要将加密字段先解密成base64,然后在进行解密,如下所示: 注意与php对接不能用AES/CBC/NoPadding方式,这个方式会导致后面出现乱码或者...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,580
精华内容 1,032
关键字:

aes乱码解密