From cd2be4c409793d0c92f57498e5b43a45a8b1f8dc Mon Sep 17 00:00:00 2001 From: tursom Date: Mon, 2 Mar 2020 00:36:29 +0800 Subject: [PATCH] update RSA --- src/main/kotlin/cn/tursom/core/encrypt/RSA.kt | 170 ++++++++++-------- 1 file changed, 100 insertions(+), 70 deletions(-) diff --git a/src/main/kotlin/cn/tursom/core/encrypt/RSA.kt b/src/main/kotlin/cn/tursom/core/encrypt/RSA.kt index cac375f..3ce6251 100644 --- a/src/main/kotlin/cn/tursom/core/encrypt/RSA.kt +++ b/src/main/kotlin/cn/tursom/core/encrypt/RSA.kt @@ -1,81 +1,111 @@ package cn.tursom.core.encrypt import java.security.KeyFactory +import java.security.KeyPair import java.security.KeyPairGenerator +import java.security.Signature import java.security.interfaces.RSAPrivateKey import java.security.interfaces.RSAPublicKey import java.security.spec.X509EncodedKeySpec import javax.crypto.Cipher -class RSA : Encrypt { - val publicKey: RSAPublicKey - - private val cipher = Cipher.getInstance("RSA")!! - - private val encryptCipher = Cipher.getInstance("RSA")!! - private val decryptCipher: Cipher? - - constructor() { - val keyPairGenerator = KeyPairGenerator.getInstance("RSA") - keyPairGenerator.initialize(1024)//512-65536 & 64的倍数 - val keyPair = keyPairGenerator.generateKeyPair() - publicKey = keyPair.public as RSAPublicKey - encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey) - decryptCipher = Cipher.getInstance("RSA")!! - decryptCipher.init(Cipher.DECRYPT_MODE, keyPair.private as RSAPrivateKey) - } - - constructor(publicKey: RSAPublicKey) { - this.publicKey = publicKey - encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey) - decryptCipher = null - } - - constructor(publicKey: ByteArray) : this(KeyFactory.getInstance("RSA").generatePublic(X509EncodedKeySpec(publicKey)) as RSAPublicKey) - - override fun encrypt(data: ByteArray, offset: Int, size: Int): ByteArray { - return if (size < 117) - encryptCipher.doFinal(data, offset, size) - else { - val buffer = ByteArray(size / 117 * 128 + 128) - var readPosition = offset - var decodeIndex = 0 - - while (readPosition + 117 < size) { - decodeIndex += cipher.doFinal(data, readPosition, 117, buffer, decodeIndex) - readPosition += 117 - } - decodeIndex += cipher.doFinal(data, readPosition, size - readPosition, buffer, decodeIndex) - - buffer.copyOf(decodeIndex) - } - } - - override fun decrypt(data: ByteArray, offset: Int, size: Int): ByteArray { - return if (data.size < 128) { - decryptCipher!!.doFinal(data, offset, size) - } else { - val buffer = ByteArray(size / 128 * 117 + 11) - var readPostion = offset - var decodeIndex = 0 - - while (readPostion + 128 < size) { - decodeIndex += cipher.doFinal(data, readPostion, 128, buffer, decodeIndex) - readPostion += 128 - } - decodeIndex += cipher.doFinal(data, readPostion, size - readPostion, buffer, decodeIndex) - buffer.copyOf(decodeIndex) - } - } - - override fun encrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int): Int { - return encryptCipher.doFinal(data, offset, 128, buffer, bufferOffset) - } - - override fun decrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int): Int { - return decryptCipher!!.doFinal(data, offset, 128, buffer, bufferOffset) - } - - class NoPrivateKeyException(message: String? = null) : Exception(message) +@Suppress("unused") +class RSA(val publicKey: RSAPublicKey, val privateKey: RSAPrivateKey? = null) : Encrypt { + val publicKeyEncoded get() = publicKey.encoded!! + val privateKeyEncoded get() = privateKey?.encoded + + private val encryptCipher = Cipher.getInstance("RSA")!! + private val decryptCipher = Cipher.getInstance("RSA")!! + + init { + encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey) + if (privateKey != null) decryptCipher.init(Cipher.DECRYPT_MODE, privateKey) + } + + constructor(keyPair: KeyPair) : this(keyPair.public as RSAPublicKey, keyPair.private as RSAPrivateKey) + + constructor(keySize: Int = 1024) : this(KeyPairGenerator.getInstance("RSA").let { + it.initialize(keySize) + it.generateKeyPair() + }) + + constructor(publicKey: ByteArray) : this(KeyFactory.getInstance("RSA").generatePublic(X509EncodedKeySpec(publicKey)) as RSAPublicKey) + + override fun encrypt(data: ByteArray, offset: Int, size: Int): ByteArray { + return if (size < 117) + encryptCipher.doFinal(data, offset, size) + else { + val buffer = ByteArray(size / 117 * 128 + 128) + var readPosition = offset + var decodeIndex = 0 + + while (readPosition + 117 < size) { + decodeIndex += encryptCipher.doFinal(data, readPosition, 117, buffer, decodeIndex) + readPosition += 117 + } + decodeIndex += encryptCipher.doFinal(data, readPosition, size - readPosition, buffer, decodeIndex) + + buffer.copyOf(decodeIndex) + } + } + + override fun decrypt(data: ByteArray, offset: Int, size: Int): ByteArray { + return if (data.size < 128) { + decryptCipher.doFinal(data, offset, size) + } else { + val buffer = ByteArray(size / 128 * 117 + 11) + var readPostion = offset + var decodeIndex = 0 + + while (readPostion + 128 < size) { + decodeIndex += decryptCipher.doFinal(data, readPostion, 128, buffer, decodeIndex) + readPostion += 128 + } + decodeIndex += decryptCipher.doFinal(data, readPostion, size - readPostion, buffer, decodeIndex) + buffer.copyOf(decodeIndex) + } + } + + override fun encrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int): Int { + return encryptCipher.doFinal(data, offset, 128, buffer, bufferOffset) + } + + override fun decrypt(data: ByteArray, buffer: ByteArray, bufferOffset: Int, offset: Int, size: Int): Int { + return decryptCipher.doFinal(data, offset, 128, buffer, bufferOffset) + } + + fun sign(data: ByteArray): ByteArray { + val signature: Signature = Signature.getInstance("MD5withRSA") + signature.initSign(privateKey) + signature.update(data) + return signature.sign() + } + + fun verify(data: ByteArray, sign: ByteArray): Boolean { + val signature = Signature.getInstance("MD5withRSA") + signature.initVerify(publicKey) + signature.update(data) + return signature.verify(sign) + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as RSA + + if (publicKey != other.publicKey) return false + if (privateKey != other.privateKey) return false + + return true + } + + override fun hashCode(): Int { + var result = publicKey.hashCode() + result = 31 * result + (privateKey?.hashCode() ?: 0) + return result + } + + class NoPrivateKeyException(message: String? = null) : Exception(message) } \ No newline at end of file