The RSA algorithm can only encrypt data that has a maximum byte length of the RSA key length in bits divided with eight minus eleven padding bytes, i.e. number of maximum bytes = key length in bits / 8 - 11.
使用RSA时,数据过长会报错,如:
javax.crypto.IllegalBlockSizeException: input must be under 256 bytes
因此,基本上,您将密钥长度除以8 -11(如果有填充)。例如,如果您具有2048位密钥,则可以加密2048/8 = 256字节(如果有填充则为11字节)。因此,可以使用更大的密钥,也可以使用对称密钥加密数据,然后使用rsa加密该密钥(推荐的方法)
参考:https://stackoverflow.com/questions/10007147/getting-a-illegalblocksizeexception-data-must-not-be-longer-than-256-bytes-when
通过分段加密解决
1.生成公钥私钥
@Throws(Exception::class)
fun genKeyPair(): Map<String?, String> {
val keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM)
keyPairGen.initialize(2048)
val keyPair = keyPairGen.generateKeyPair()
val publicKey = keyPair.public as RSAPublicKey
val privateKey = keyPair.private as RSAPrivateKey
val keyMap: MutableMap<String?, String> = HashMap(2)
keyMap[PUBLIC_KEY] = Base64.encodeToString(publicKey.encoded, Base64.DEFAULT)
keyMap[PRIVATE_KEY] = Base64.encodeToString(privateKey.encoded, Base64.DEFAULT)
return keyMap
}
2.公钥加密
@Throws(Exception::class)
fun encryptByPublicKey(data: ByteArray, publicKey: String?): ByteArray {
val keyBytes: ByteArray = Base64.decode(publicKey, Base64.DEFAULT)
val x509KeySpec = X509EncodedKeySpec(keyBytes)
val keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
val publicK: Key = keyFactory.generatePublic(x509KeySpec)
// 对数据加密
val cipher = Cipher.getInstance(keyFactory.algorithm)
cipher.init(Cipher.ENCRYPT_MODE, publicK)
val inputLen = data.size
val out = ByteArrayOutputStream()
var offSet = 0
var cache: ByteArray
var i = 0
// 对数据分段加密
while (inputLen - offSet > 0) {
cache = if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK)
} else {
cipher.doFinal(data, offSet, inputLen - offSet)
}
out.write(cache, 0, cache.size)
i++
offSet = i * MAX_ENCRYPT_BLOCK
}
val encryptedData = out.toByteArray()
out.close()
return encryptedData
}
3.私钥解密
@Throws(Exception::class)
fun decryptByPrivateKey(encryptedData: ByteArray, privateKey: String?): ByteArray {
val keyBytes: ByteArray = Base64.decode(privateKey, Base64.DEFAULT)
val pkcs8KeySpec = PKCS8EncodedKeySpec(keyBytes)
val keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
val privateK: Key = keyFactory.generatePrivate(pkcs8KeySpec)
val cipher = Cipher.getInstance(keyFactory.algorithm)
cipher.init(Cipher.DECRYPT_MODE, privateK)
val inputLen = encryptedData.size
val out = ByteArrayOutputStream()
var offSet = 0
var cache: ByteArray
var i = 0
// 对数据分段解密
while (inputLen - offSet > 0) {
cache = if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK)
} else {
cipher.doFinal(encryptedData, offSet, inputLen - offSet)
}
out.write(cache, 0, cache.size)
i++
offSet = i * MAX_DECRYPT_BLOCK
}
val decryptedData = out.toByteArray()
out.close()
return decryptedData
}
4.调用方法:
val keyMap: Map<String?, String?> = RSACrypt.genKeyPair()
val publicKey = keyMap[RSACrypt.PUBLIC_KEY]
val privateKey = keyMap[RSACrypt.PRIVATE_KEY]
val source =
"身高一米七左右,标准的九头身,五官立体宛如艺术大师鬼斧神工之作,肌肤赛雪,宛如白玉般似能反射光彩。" +
"“我和茹雪两情相悦,但对我们而言,你是第三者,所以请你自己主动退出,我愿意给你一笔钱,你开个价码吧!”啪,一声清脆的响声,干净利落地狠狠扇在韩斌的脸上。" +
"乔智愿意当陶家的女婿,除了偿还父亲欠下的人情债之外,还有一个重要原因,陶茹雪本身出众,是琼金一枝花,知名度高,追求者众多。"
val data = source.encodeToByteArray()
val encodedData: ByteArray = RSACrypt.encryptByPublicKey(data, publicKey)
Log.w("rsa", "加密后文字:${Base64.encodeToString(encodedData, Base64.DEFAULT)}")
val decodedData: ByteArray = RSACrypt.decryptByPrivateKey(encodedData, privateKey)
Log.w("rsa", "解密后文字: \r\n${String(decodedData)}")
完整代码
object RSACrypt {
/**
* 加密算法RSA
*/
const val KEY_ALGORITHM = "RSA"
/**
* 签名算法
*/
const val SIGNATURE_ALGORITHM = "MD5withRSA"
/**
* 获取公钥的key
*/
const val PUBLIC_KEY = "RSAPublicKey"
/**
* 获取私钥的key
*/
const val PRIVATE_KEY = "RSAPrivateKey"
/**
* RSA最大加密明文大小
*/
private const val MAX_ENCRYPT_BLOCK = 245
/**
* RSA最大解密密文大小
*/
private const val MAX_DECRYPT_BLOCK = 256
/**
* 生成密钥对(公钥和私钥)
* @return
* @throws Exception
*/
@Throws(Exception::class)
fun genKeyPair(): Map<String?, String> {
val keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM)
keyPairGen.initialize(2048)
val keyPair = keyPairGen.generateKeyPair()
val publicKey = keyPair.public as RSAPublicKey
val privateKey = keyPair.private as RSAPrivateKey
val keyMap: MutableMap<String?, String> = HashMap(2)
keyMap[PUBLIC_KEY] = Base64.encodeToString(publicKey.encoded, Base64.DEFAULT)
keyMap[PRIVATE_KEY] = Base64.encodeToString(privateKey.encoded, Base64.DEFAULT)
return keyMap
}
/**
* 私钥解密
*
* @param encryptedData 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
@Throws(Exception::class)
fun decryptByPrivateKey(encryptedData: ByteArray, privateKey: String?): ByteArray {
val keyBytes: ByteArray = Base64.decode(privateKey, Base64.DEFAULT)
val pkcs8KeySpec = PKCS8EncodedKeySpec(keyBytes)
val keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
val privateK: Key = keyFactory.generatePrivate(pkcs8KeySpec)
val cipher = Cipher.getInstance(keyFactory.algorithm)
cipher.init(Cipher.DECRYPT_MODE, privateK)
val inputLen = encryptedData.size
val out = ByteArrayOutputStream()
var offSet = 0
var cache: ByteArray
var i = 0
// 对数据分段解密
while (inputLen - offSet > 0) {
cache = if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK)
} else {
cipher.doFinal(encryptedData, offSet, inputLen - offSet)
}
out.write(cache, 0, cache.size)
i++
offSet = i * MAX_DECRYPT_BLOCK
}
val decryptedData = out.toByteArray()
out.close()
return decryptedData
}
/**
*
* 公钥加密
*
* @param data 源数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
@Throws(Exception::class)
fun encryptByPublicKey(data: ByteArray, publicKey: String?): ByteArray {
val keyBytes: ByteArray = Base64.decode(publicKey, Base64.DEFAULT)
val x509KeySpec = X509EncodedKeySpec(keyBytes)
val keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
val publicK: Key = keyFactory.generatePublic(x509KeySpec)
// 对数据加密
val cipher = Cipher.getInstance(keyFactory.algorithm)
cipher.init(Cipher.ENCRYPT_MODE, publicK)
val inputLen = data.size
val out = ByteArrayOutputStream()
var offSet = 0
var cache: ByteArray
var i = 0
// 对数据分段加密
while (inputLen - offSet > 0) {
cache = if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK)
} else {
cipher.doFinal(data, offSet, inputLen - offSet)
}
out.write(cache, 0, cache.size)
i++
offSet = i * MAX_ENCRYPT_BLOCK
}
val encryptedData = out.toByteArray()
out.close()
return encryptedData
}
}
评论 (0)