[英]how to use (RSA/ECB/PKCS1Padding) in android
About a year ago, I wrote an application for Android and used a class in it RSA In this class, there was the following code snippet and the application worked大约一年前,我为 Android 编写了一个应用程序,并在其中使用了一个 class 的 RSA 在这个 class 中,有以下代码片段并且该应用程序可以运行
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")
But when I re-entered the application code, I did not open the new encrypted information to change the private key until I changed the above code line to the following code line.但是当我重新进入应用程序代码时,我并没有打开新的加密信息来更改私钥,直到我将上面的代码行更改为下面的代码行。
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
The problem is that if I replace the above code snippet in class RSA it is no longer possible to open previously encrypted information (with the same keys as before).问题是,如果我在 class RSA 中替换上面的代码片段,就无法再打开以前加密的信息(使用与以前相同的密钥)。 And I see the following error
我看到以下错误
javax.crypto.BadPaddingException: error:04000084:RSA routines:OPENSSL_internal:PKCS_DECODING_ERROR
RSA decryption RSA解密
public static byte[] decryptByPrivateKey(byte[] data, String key)
throws Exception {
byte[] keyBytes = decryptBASE64(key);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
// Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
RSA key pairs can be used within different RSA based schemes, such as PKCS#1 and OAEP padding for encryption, and PKCS#1 and PSS padding for signing. RSA 密钥对可以在不同的基于 RSA 的方案中使用,例如用于加密的 PKCS#1 和 OAEP 填充,以及用于签名的 PKCS#1 和 PSS 填充。 However, there is only one key pair generation possible, which is simply denoted
"RSA"
.但是,只能生成一个密钥对,简称为
"RSA"
。
If only "RSA"
is used as input string it will use the defaults set for the specific cryptography provider, which is - in this case - the first provider that implements RSA using keys in software.如果只使用
"RSA"
作为输入字符串,它将使用为特定加密提供程序设置的默认值,在这种情况下,它是第一个使用软件中的密钥实现 RSA 的提供程序。 Apparently that's different on Android from PKCS#1 padding (assuming that you still use the original list of providers, of course).显然,Android 与 PKCS#1 填充不同(当然,假设您仍然使用原始提供者列表)。 One stupid thing in Java is that you cannot programmatically find out which defaults are used;
Java 中的一件愚蠢的事情是您无法以编程方式找出使用了哪些默认值;
getAlgorithm()
ususally just returns the string you've provided earlier. getAlgorithm()
通常只返回您之前提供的字符串。 The only thing you can do is to get the provider using getProvider()
and then lookup the defaults...您唯一可以做的就是使用
getProvider()
获取提供者,然后查找默认值...
I would never go for any defaults (except for SecureRandom
defaults) as it is unspecified which defaults will be used for Java. Always specify the algorithm in full;我永远不会将 go 用于任何默认值(
SecureRandom
默认值除外),因为未指定哪些默认值将用于 Java。始终完整指定算法; your earlier string was fine.您之前的字符串很好。
My function我的 function
private fun getEncryptCodeWord(publicKey:String, codeWord:String):String{
try{
val publicBytes = Base64.decode(publicKey, Base64.NO_WRAP)
val keySpec = X509EncodedKeySpec(publicBytes)
val keyFactory = KeyFactory.getInstance("RSA")
val pubKey = keyFactory.generatePublic(keySpec)
val encryptCodeWord = Cipher.getInstance("RSA/ECB/PKCS1Padding")
.apply { init(Cipher.ENCRYPT_MODE, pubKey) }
.doFinal(codeWord.toByteArray())
return Base64.encodeToString(encryptCodeWord, Base64.NO_WRAP)
}
catch (ex:Exception){
Crash.recordException(ex)
Crash.setKey("error_get_encrypt_code_word",ex.message)
}
return codeWord
}
and for RSA/ECB/OAEPWithSHA-256AndMGF1Padding和 RSA/ECB/OAEPWithSHA-256AndMGF1Padding
private fun getEncryptCodeWord(publicKey:String,codeWord:String):String{
try{
val publicBytes = Base64.decode(publicKey, Base64.NO_WRAP)
val keySpec = X509EncodedKeySpec(publicBytes)
val keyFactory = KeyFactory.getInstance("RSA")
val pubKey = keyFactory.generatePublic(keySpec)
val sp = OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec("SHA-1"), PSource.PSpecified.DEFAULT)
val encrypt = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding")
encrypt.init(Cipher.ENCRYPT_MODE, pubKey, sp)
val encryptCodeWord = encrypt.doFinal(codeWord.toByteArray())
return Base64.encodeToString(encryptCodeWord, Base64.NO_WRAP)
}
catch (ex:Exception){
Crash.recordException(ex)
Crash.setKey("error_get_encrypt_code_word",ex.message)
}
return codeWord
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.