java aes CBC的填充方式发现

如下的java代码,手动对block进行填充后,使其为16的整数倍后,加密的时候竟然强行再填充了16位,我在尝试用golang实现这段加密时,反复修改了很久,发现golang版的总是比java加密出来并base64的结果少了20位,于是把各个步骤中间结果打出来,发现并没有什么不同,然后尝试在golang后面强行追加了16个填充,那么填充什么呢?没错,我就是从0x0到0x10一个一个试出来的,最后发现当填充16个0x10时,golang跟java的加密结果就完全一样了,下面贴出golang跟java的两个代码:

PS: iv和key都是一模一样的。得到一个教训,当golang跟java在两种相同的模式下面如果加密出来的密文不同的时候就去尝试修改填充的方法吧,多尝试几次总是可以的。

java:

public static String aesEncrypt2(String appsecret, String data) throws Exception
    {
        //设置加密密钥
        String key = appsecret.substring(16);
        System.out.println(key);
        SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
        //初始化向量
        System.out.println("md5: " + DigestUtils.md5Hex(appsecret).substring(0, 16));
        String iv = DigestUtils.md5Hex(appsecret).substring(0, 16);
        IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
        //设置加密模式
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        //填充算法
        int blockSize = cipher.getBlockSize();
        byte[] dataBytes = data.getBytes();
        int plaintextLength = dataBytes.length;
        if (plaintextLength % blockSize != 0) {
            plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
        }
        byte[] plaintext = new byte[plaintextLength];
        System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
        System.out.println("填充后长度=" + plaintext.length);
        for(int i = 0;i < plaintext.length; i++)
        System.out.print(plaintext[i] + " ");
        //加密
        cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
        byte[] encrypted = cipher.doFinal(plaintext);
        System.out.println("");
        for(int i = 0;i < encrypted.length;i++)
            System.out.print(encrypted[i] + " ");
        System.out.println("");
        return Base64.encodeBase64String(encrypted);
    }

golang:

func GetMD5(cipherText string) string {
    md5Ctx := md5.New()
    md5Ctx.Write([]byte(cipherText))
    cipherStr := md5Ctx.Sum(nil)
    return hex.EncodeToString(cipherStr)
}

func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
    padding := blockSize - len(ciphertext)%blockSize
    //    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    for i := 0; i < padding; i++ {
        ciphertext = append(ciphertext, 0x0)
    }
    for i := 16; i < 32; i++ {
        ciphertext = append(ciphertext, 0x10)
    }
    fmt.Println(ciphertext)
    fmt.Printf("blocksieze[%d]\n", len(ciphertext))
    //    return append(ciphertext, padtext...)
    return ciphertext
}

func AesEncrypt(secret, data string) string {
    if len(secret) < 16 {
        log.Errorf("AesEncrypt secret[%s] length less 16")
        return ""
    }
    fmt.Println(secret[16:])
    key := []byte(secret[16:])
    iv := []byte(GetMD5(secret)[:16])
    fmt.Println("md5: " + GetMD5(secret)[:16])
    block, err := aes.NewCipher(key)
    if err != nil {
        log.Errorf("key error[%v]", err)
        return ""
    }
    ecb := cipher.NewCBCEncrypter(block, iv)
    content := PKCS5Padding([]byte(data), block.BlockSize())
    crypted := make([]byte, len(content))
    ecb.CryptBlocks(crypted, content)
    fmt.Println(crypted)
    return base64.StdEncoding.EncodeToString(crypted)
}

时间: 2024-11-09 13:23:59

java aes CBC的填充方式发现的相关文章

AES/CBC/PKCS7Padding加密方式

在网上找了大半天资料,终于找到一个可以用的 public static class AES { // 算法名称 final static String KEY_ALGORITHM = "AES"; // 加解密算法/模式/填充方式 final static String algorithmStr = "AES/CBC/PKCS7Padding"; // private static Key key; private static Cipher cipher; boo

JAVA AES CBC 加密 解密

AES 256 , KEY 的长度为 32字节(32*8=256bit). AES 128 , KEY 的长度为 16字节(16*8=128bit) CBC 模式需要IV, IV的值是固定写死,还是当参数传入,自己看情况.IV的长度没研究,这里用的是16字符. java PKCS5Padding 对应 C#.NET 的 PKCS7 . 明文,KEY和IV 三者 string 转 byte[] 时要统一编码,如UTF-8. 加密后 cipher.doFinal() 得到密文byte[] ,是直接转

java PKCS7Padding 加密Cannot find any provider supporting AES/CBC/PKCS7Padding 解决办法

在java中用aes256进行加密,但是发现java里面不能使用PKCS7Padding,而java中自带的是PKCS5Padding填充,那解决办法是,通过BouncyCastle组件来让java里面支持PKCS7Padding填充. 説辣么多不如上代码: public class AESUtil { /** * Encodes a String in AES-256 with a given key * * @param context * @param password * @param

Java 使用AES/CBC/PKCS7Padding 加解密字符串

介于java 不支持PKCS7Padding,只支持PKCS5Padding 但是PKCS7Padding 和 PKCS5Padding 没有什么区别要实现在java端用PKCS7Padding填充,需要用到bouncycastle组件来实现 所以需要一个jar 来支持.bcprov-jdk16-146.jar 下载地址:http://central.maven.org/maven2/org/bouncycastle/bcprov-jdk16/1.46/bcprov-jdk16-1.46.jar

linux上java解加密(AES/CBC)异常:java.lang.SecurityException: JCE cannot authenticate the provider BC办法

用mapreduce做数据清洗的时候,需要对数据进行解密,加密方法是:AES/CBC/PKCS7Padding,由于java本身不支持,需要添加依赖,用的依赖是: 1 <dependency> 2 <groupId>org.bouncycastle</groupId> 3 <artifactId>bcprov-jdk15on</artifactId> 4 <version>1.56</version> 5 </dep

C++调用openssl实现DES加密解密cbc模式 zeropadding填充方式 pkcs5padding填充方式 pkcs7padding填充方式

============================================== des   cbc  加密 zeropadding填充方式 ============================================== //加密 cbc zeropadding 自己实现 std::string des_cbc_zero_encrypt(const std::string &clearText, const std::string &key) { static u

java实现AES/CBC/pack5padding加解密算法

最近要测试一个借口,借口的传值参数是使用AES加密,偏移量为0000000000000000,秘钥:12345678901234567890123456789012,加密后内容转成16进制发送,用网上的代码一直没实现,最后发送是因为jre的两个jar包需要升级,支持key大于16位. 两个jar包:US_export_policy.jar.local_policy.jar,下载地址:https://files.cnblogs.com/files/tech-test/security.zip 代码

java AES加密解密

近些年DES使用越来越少,原因就在于其使用56位密钥,比较容易被破解,近些年来逐渐被AES替代,AES已经变成目前对称加密中最流行算法之一:AES可以使用128.192.和256位密钥,并且用128位分组加密和解密数据.本文就简单介绍如何通过JAVA实现AES加密. 因为在做接口 webservice的时候接受穿过的数据 是xml 加密为二进制 byte[]   下面直接看代码 : import java.io.UnsupportedEncodingException; import java.

AES CBC/CTR 加解密原理

So, lets look at how CBC works first. The following picture shows the encryption when using CBC (in this case, using AES as the cipher). Basically, Cipher-Block-Chaining means that previous to putting the cleartext data block into the cipher itself (