Android 平台如何使用 RSA 算法进行加解密?
发布于: 刚刚
1.知识点
RSA 公开密钥密码体制的原理是:根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
2.原理
3.代码
RSAUtil.kt
import java.lang.StringBuilder
import java.lang.reflect.Constructor
import java.security.*
import java.security.interfaces.RSAPrivateKey
import java.security.interfaces.RSAPublicKey
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
import javax.crypto.Cipher
class RSAUtil private constructor(){
companion object{
@Volatile
private var instance: RSAUtil? = null
private val instanceLock = Any()
fun getInstance(): RSAUtil {
val tmp = instance
if (tmp != null) {
return tmp
}
synchronized(instanceLock) {
if (instance == null) {
instance = RSAUtil()
}
return instance!!
}
}
}
private val keyPair : KeyPair = generateRSAKeyPair(1024)
fun getPublicKey(): ByteArray {
val rsaPublicKey: RSAPublicKey = keyPair.public as RSAPublicKey
return rsaPublicKey.encoded
}
fun getPrivateKey(): ByteArray {
val rsaPrivateKey: RSAPrivateKey = keyPair.private as RSAPrivateKey
return rsaPrivateKey.encoded
}
}
/**RSA算法 */
val RSA = "RSA"
/**加密方式,android的*/
// public static final String TRANSFORMATION = "RSA/None/NoPadding";
/**加密方式,android的 */
// public static final String TRANSFORMATION = "RSA/None/NoPadding";
/**加密方式,标准jdk的 */
val TRANSFORMATION = "RSA/None/PKCS1Padding"
/** 生成密钥对,即公钥和私钥。key长度是512-2048,一般为1024 */
@Throws(NoSuchAlgorithmException::class)
fun generateRSAKeyPair(keyLength: Int): KeyPair {
val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(RSA)
kpg.initialize(keyLength)
return kpg.genKeyPair()
}
/** 获取公钥,打印为48-12613448136942-12272-122-913111503-126115048-12...等等一长串用-拼接的数字 */
fun getPublicKey(keyPair: KeyPair): ByteArray {
val rsaPublicKey: RSAPublicKey = keyPair.public as RSAPublicKey
return rsaPublicKey.encoded
}
/** 获取私钥,同上 */
fun getPrivateKey(keyPair: KeyPair): ByteArray {
val rsaPrivateKey: RSAPrivateKey = keyPair.private as RSAPrivateKey
return rsaPrivateKey.encoded
}
/** 使用公钥加密 */
@Throws(Exception::class)
fun encryptByPublicKey(data: ByteArray?, publicKey: ByteArray?): ByteArray? {
// 得到公钥对象
val keySpec = X509EncodedKeySpec(publicKey)
val keyFactory: KeyFactory = KeyFactory.getInstance("RSA")
val pubKey: PublicKey = keyFactory.generatePublic(keySpec)
// 加密数据
val cp: Cipher = Cipher.getInstance(TRANSFORMATION)
cp.init(Cipher.ENCRYPT_MODE, pubKey)
return cp.doFinal(data)
}
/** 使用私钥解密 */
@Throws(Exception::class)
fun decryptByPrivateKey(encrypted: ByteArray?, privateKey: ByteArray?): ByteArray? {
// 得到私钥对象
val keySpec = PKCS8EncodedKeySpec(privateKey)
val kf: KeyFactory = KeyFactory.getInstance(RSA)
val keyPrivate: PrivateKey = kf.generatePrivate(keySpec)
// 解密数据
val cp: Cipher = Cipher.getInstance(TRANSFORMATION)
cp.init(Cipher.DECRYPT_MODE, keyPrivate)
return cp.doFinal(encrypted)
}
fun byteArray2String(bytes: ByteArray?): String? {
if (null == bytes) return null
val stringBuffer = StringBuilder()
for (byte in bytes) {
stringBuffer.append(byte)
}
return stringBuffer.toString()
}
复制代码
Test.kt
import com.nufront.trunking.common.system.LogUtil
import java.nio.charset.Charset
import java.security.KeyPair
fun test() {
val data = "hello world123321"
try {
val keyLength = 1024
//生成密钥对
val keyPair: KeyPair = generateRSAKeyPair(keyLength)
//获取公钥
val publicKey: ByteArray = getPublicKey(keyPair)
//获取私钥
val privateKey: ByteArray = getPrivateKey(keyPair)
//用公钥加密
val encrypt = encryptByPublicKey(data.toByteArray(), publicKey)
LogUtil.e("cclin", "加密后的数据:" + byteArray2String(encrypt))
//用私钥解密
val decrypt = decryptByPrivateKey(encrypt, privateKey)
LogUtil.e("cclin", "解密后的数据:" + String(decrypt!!, Charset.defaultCharset()))
} catch (e: Exception) {
e.printStackTrace()
LogUtil.printException(e)
}
}
复制代码
划线
评论
复制
发布于: 刚刚阅读数: 2
版权声明: 本文为 InfoQ 作者【Changing Lin】的原创文章。
原文链接:【http://xie.infoq.cn/article/7415be092a7a1f30a93ad6a40】。文章转载请联系作者。
Changing Lin
关注
获得机遇的手段远超于固有常规之上~ 2020.04.29 加入
我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。
评论