如下的java代码,手动对block进行填充后,使其为16的整数倍后,加密的时候竟然强行再填充了16位,我在尝试用golang实现这段加密时,反复修改了很久,发现golang版的总是比java加密出来并base64的结果少了20位,于是把各个步骤中间结果打出来,发现并没有什么不同,然后尝试在golang后面强行追加了16个填充,那么填充什么呢?没错,我就是从0x0到0x10一个一个试出来的,最后发现当填充16个0x10时,golang跟java的加密结果就完全一样了,其实是按照pkcs5的填充规则的,例如需要填充n位,那么填充的值就是n,下面贴出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 := ; i < padding; i++ {
ciphertext = append(ciphertext, 0x0)
}
for i := ; i < ; 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) < {
log.Errorf("AesEncrypt secret[%s] length less 16")
return ""
}
fmt.Println(secret[:])
key := []byte(secret[:])
iv := []byte(GetMD5(secret)[:])
fmt.Println("md5: " + GetMD5(secret)[:])
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)
}

最新文章

  1. openjudge 螺旋加密
  2. .NET获取服务器信息,如服务器版本、IIS等
  3. ngCordova插件安装使用
  4. linux tmp75 /dev/i2c-* 获取数据 demo
  5. AFNetworking源码分析
  6. web2py相关-------------------------------(一)初遇
  7. [iOS] 创建第一个应用程序项目
  8. 转化率最高的16个WordPress 电子商务主题
  9. 从源代码上分析ListView的addHeaderView和setAdapter的调用顺序
  10. Ext4.1 , #Ext4.2
  11. UDP网络程序模型设计
  12. c++ cout、cin、endl
  13. constructor属性解析
  14. MySQL - 查看慢SQL
  15. nyoj860(01变形)
  16. idea集成项目管理工具 --- Maven 并且【配置tomcat】
  17. div框选中状态,倒三角样式
  18. sed: unix与doc换行的转换
  19. PHP——分页显示的完善(加查询,用类简化sql语句)
  20. Python基础笔记系列十四:python无缝调用c程序

热门文章

  1. 51Nod 1004 n^n的末位数字
  2. golang 调用windows API 中文的处理
  3. 网络流 P2770 航空路线问题
  4. python学习——读取染色体长度(四:获取最长染色体的编号)
  5. Codeforces Round #539 (Div. 2) - C. Sasha and a Bit of Relax(思维题)
  6. 算法学习之BFS、DFS入门
  7. 这可能是最简单的Page Object库
  8. openstack第二章:glance
  9. 小小知识点(八)——星座图与PSK、QAM调制的关系
  10. ansible roles