JCA密钥相关类关系一览 , 如下:
文章插图
文章插图
常见问题密文无法解密问题有时 , 在使用密码算法时 , 会发现别人提供的密文使用正确的密钥却无法解密出来 , 特别容易发生在跨语言的情况下 , 如加密方使用的C#语言 , 而解密方却使用的Java 。
遇到这种情况 , 你需要和对方认真确认加密时使用的加密模式、填充模式以及IV等密码参数是否完全一致 。
如AES算法加密模式有
ECB
、CBC
、CFB
、CTR
、GCM
等 , 填充模式有PKCS#5
, ISO 10126
, ANSI X9.23
等 , 以及对方是使用了固定的IV向量还是将IV向量拼在了密文中 , 这些都需要确认清楚并与对方保持一致才能正确解密 。签名失败问题签名失败也是使用密码算法时常见的情况 , 比如对方生成的MD5值与你生成的MD5不一致 , 常见有2种原因 , 如下:1. 使用的字符编码不一致导致密码算法为了通用性 , 操作对象都是字节数组 , 而你要签名的对象一般是字符串 , 因此你需要将字符串转为字节数组之后再做md5运算 , 如下:
- 调用方:
md5(str.getBytes())
- 服务方:
md5(str.getBytes())
getBytes()
函数中 , getBytes()
函数默认会使用操作系统的字符编码将字符串转为字节数组 , 而中文Windows
默认字符编码是GBK , 而Linux
默认是UTF-8 , 这就导致当str中有中文时 , 调用方与服务方获取到的字节数组是不一样的 , 那生成的MD5值当然也不一样了 。因此 , 强烈推荐在使用
getBytes()
函数时 , 传入统一的字符编码 , 如下:- 调用方:
md5(str.getBytes("UTF-8"))
- 服务方:
md5(str.getBytes("UTF-8"))
这样就能有效地避过这个非常隐晦的坑了 。
&
字符转义为\u0026
, 但如果服务端做json反序列化时没有做反转义 , 这会导致两边计算的签名值不一样 , 如下:- 调用方:
md5("&")
- 服务方:
md5("\\u0026")
这也是一个非常隐晦的坑 , 如Gson默认就会有这种行为 , 可使用new GsonBuilder().disableHtmlEscaping()
禁用 。
PKCS8
、X.509
、ASN.1
、DER
、PEM
等 , 接下来就来澄清下这些名词是什么 , 以及它们之间的关系 。首先 , 了解3个概念 , 如下:
- 密钥:包括对称密钥与非对称密钥等 。
- 证书:包含用户或网站的身份信息、公钥 , 以及CA的签名 。
- 密钥库:用于存储密钥与证书的仓库 。
经验总结扩展阅读
- [WPF] 抄抄超强的苹果官网滚动文字特效实现
- Java函数式编程:一、函数式接口,lambda表达式和方法引用
- 不妨试试更快更小更灵活Java开发框架Solon
- 11 微服务架构学习与思考:开源 API 网关02-以 Java 为基础的 API 网关详细介绍
- java 新特性之 Stream API
- java 入土--集合详解
- 4 Java I/O:AIO和NIO中的Selector
- 2023容易暴富的星座女实现质的飞跃
- 通过 Github Action 实现定时推送天气预报
- 3 Java I/O:NIO中的Buffer