1.一般流程
1.服务端生成RSA公钥私钥
2.客户端向服务端请求RSA公钥
3.客户端收到的RSA公钥,使用RSA公钥加密AES密发送给服务端
4.服务端收到AES公钥后,客户端发送消息将会使用AES密钥加密,服务端使用AES密钥解密
2.具体实现
主要为客户端的代码实现
2.1AES密钥生成
/**
* 生成密钥
*/
fun generateRandomKey(): ByteArray {
val keygen: KeyGenerator = try {
KeyGenerator.getInstance("AES")
} catch (e: NoSuchAlgorithmException) {
throw RuntimeException(" generateRandomKey fail!", e)
}
val random = SecureRandom()
keygen.init(random)
val key: Key = keygen.generateKey()
return key.encoded
}
2.2使用RSA公钥加密AES密钥
公钥会以模(modulus)和公钥指数(publicExponent)的形式收到,可将模和公钥指数转换为公钥后使用
/**
* 使用RSA公钥加密
* @param source 需要加密的数据
* @param modulus 模数
* @param publicExponent 公钥指数
*/
@Throws(Exception::class)
fun encrypt(source: ByteArray?, modulus: ByteArray?, publicExponent: ByteArray?): ByteArray {
if (null == modulus || null == publicExponent) return source!!
val key: Key = getPublicKey(modulus, publicExponent)
/* 得到Cipher对象来实现对源数据的RSA加密 */
val cipher = Cipher.getInstance("RSA/ECB/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, key)
/* 执行加密操作 */
return cipher.doFinal(source)
}
/**
* 使用模数、公钥指数获得公钥
* @param modulus 模数
* @param publicExponent 公钥指数
*/
private fun getPublicKey(modulus: ByteArray, publicExponent: ByteArray): PublicKey {
val bigIntModulus = BigInteger(1, modulus)
val bigIntPrivateExponent = BigInteger(1, publicExponent)
val keySpec = RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent)
val keyFactory = KeyFactory.getInstance("RSA")
return keyFactory.generatePublic(keySpec)
}
2.3使用AES密钥加密消息
/**
* 加密
* @param data 需要加密的消息
* @param key 密钥
*/
fun encrypt(data: ByteArray, key: ByteArray): ByteArray {
return try {
val len = 16 - data.size % 16
val list = data.toMutableList()
for (i in 0 until len) {
list.add(0)
}
val secretKey = SecretKeySpec(key, "AES")
val cipher = Cipher.getInstance("AES/ECB/NoPadding") // 创建密码器
cipher.init(Cipher.ENCRYPT_MODE, secretKey) // 初始化
cipher.doFinal(list.toByteArray()) // 加密
} catch (e: Exception) {
e.printStackTrace()
throw RuntimeException("encrypt fail!", e)
}
}
3.注意事项
1.加密所使用的转换模式需要两端保持一直,上面使用了RSA/ECB/NoPadding
AES/ECB/NoPadding