Can I set my PublicKey in "provider.get(RSA.PSS)" ?
thanhhoai162963 opened this issue · 11 comments
val ecdsa = provider.get(ECDSA)
val keyPairGenerator = ecdsa.keyPairGenerator(EC.Curve.P521)
val keyPair: ECDSA.KeyPair = keyPairGenerator.generateKey()
I wasn't found setPublicKey()
Hey, Im not sure what do you mean by setPublicKey. What use case do you have? What are you trying to do?
I use asymmetric encryption which connect resful api. I get rsaPublicKey from api server (not need encryption).
After I need set publickKey with rsaPublicKey and key random from local to encrypt(k) call api.
Example:
fun encryptData(dataDes: String): String? {
return try {
val c = Cipher.getInstance(Algorithm.RSA_OAEP)
c.init(Cipher.ENCRYPT_MODE, Key.rsaPublicKey()) // rsaPublicKey I get from api
val encryptOut = c.doFinal(dataDes.toByteArray()) // dataDes random char()
org.bouncycastle.util.encoders.Base64.toBase64String(encryptOut) // result "k" to call api asymmetric encryption
} catch (e: Exception) {
}
}
As far as I understand you need to decode key from binary representation and then use it. In this case you will need something like:
ECDSA:
val ecdsa = provider.get(ECDSA)
val publicKey = ecdsa.publicKeyDecoder(EC.Curve.P521).decodeFrom(EC.PublicKey.Format.RAW, keyByteArray) // or other format
// and then do anything with key verify or encryptSimilar for RSA-OAEP:
val rsa = provider.get(RSA.OAEP)
val publicKey = rsa.publicKeyDecoder(SHA256).decodeFrom(RSA.PublicKey.Format.DER) // or other format
// and then do anything with key verify or encryptDoes it helps?
val publicKey = rsa.publicKeyDecoder(SHA256).decodeFrom(RSA.PublicKey.Format.DER, myKey)
//Follow I understand, Can I set publicKey = "myKey" here?
I mean i can init val rsa = provider.get(RSA.OAEP) with myKey, after I encrypt data combine (RSA.OAEP)contain mykey as
c.init(Cipher.ENCRYPT_MODE, myKey) // rsaPublicKey I get from api
val encryptOut = c.doFinal(data) // dataDes random char()
Follow I understand, Can I set publicKey = "myKey" here?
Yeah, though, myKey should be a ByteArray, not a String. DER format is the same format which is used in JDK APIs by default for RSA keys.
fun encryptData(dataRandom: String): String? {
return try {
val c = Cipher.getInstance("RSA/ECB/OAEPPadding")
c.init(Cipher.ENCRYPT_MODE, loadPublicKey())
val encryptOut = c.doFinal(dataRandom.toByteArray())
org.bouncycastle.util.encoders.Base64.toBase64String(encryptOut)
} catch (e: Exception) {
Log.d("error:", "error")
""
}
}
@Throws(GeneralSecurityException::class, IOException::class)
private fun loadPublicKey(): PublicKey? {
val rsaPublicKey = runBlocking {
LizAiDataStore.instance.getRsaPublicKey()?.publicKey
}
val data = Base64.decode(rsaPublicKey)
val spec = X509EncodedKeySpec(data)
val fact = KeyFactory.getInstance(Algorithm.RSA)
return fact.generatePublic(spec)
}
Thanks you very much recommend you @whyoleg , after 3 days thinking, learn about
from website, ,convery swift xcode - to kotlin mutiilplatform, I still can't convert this code. Looking forward to your suggestions
Looks like I really need to create a guide for JDK APIs to cryptography-kotlin conversion, as you are not the only one who is struggling with it :)
Here is a one way to do this:
fun encryptData(data: String): String? {
val key = loadPublicKey() ?: return null
val encryptOut = key.encryptor().encrypt(data.encodeToByteArray())
return Base64.encode(encryptOut)
}
private fun loadPublicKey(): RSA.OAEP.PublicKey? {
val rsaPublicKey = runBlocking { LizAiDataStore.instance.getRsaPublicKey()?.publicKey } ?: return null
val encodedKey: ByteArray = Base64.decode(rsaPublicKey)
return CryptographyProvider.Default.get(RSA.OAEP)
.publicKeyDecoder(SHA256)
.decode(RSA.PublicKey.Format.DER, encodedKey)
}Notes:
Base64here is using kotlin Base64- I've omitted some details, to keep intention clear
Thank you @whyoleg. I generated encryptOut. But my server not decrypt . My server use dot Net rsa oeap follow:
https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.rsacryptoserviceprovider?view=netcore-3.1
keySize: 2048
Looks like .NET is using RSA OAEP with SHA1 - hint on SO: https://stackoverflow.com/a/67793433
So you need to try publicKeyDecoder(SHA1) instead
Thanks you very much @whyoleg , it working. Special thanks.
And Can I use triple des algorithm as android ?
mySecretKeyFactory = SecretKeyFactory.getInstance("DESede")
cipher = Cipher.getInstance("DESede")
key = mySecretKeyFactory?.generateSecret("DESede")