简体   繁体   English

如何在 android 中使用 (RSA/ECB/PKCS1Padding)

[英]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.

相关问题 使用RSA / ECB / PKCS1Padding进行.Net加密和Java解密 - .Net encryption and java decryption with RSA/ECB/PKCS1Padding 如何使用算法 RSA/ECB/PKCS1Padding 通过加密字符串的 node.js 进行加密 - How to encrypt through node.js of encrypted string using algorithm RSA/ECB/PKCS1Padding .NET 等效于 Java KeyFactory.getInstance "RSA"/"RSA/ECB/PKCS1Padding" - .NET equivalent of Java KeyFactory.getInstance "RSA"/"RSA/ECB/PKCS1Padding" 使用RSA / ECB / PKCS1Padding在Java中进行加密无法在.Net中解密 - Encrypted in Java using RSA/ECB/PKCS1Padding unable to decrypt in .Net 使用模量和指数的C#中的RSA / ECB / PKCS1填充解密 - RSA/ECB/PKCS1Padding Decryption in C# using Modulus and Exponent 使用RSA / ECB / PKCS1padding的Android加密问题。 它在Java和Android中给出不同的结果 - Issue in Android Encryption using RSA/ECB/PKCS1padding. It gives different results in Java and Android 如何在Java中使用给定的公钥以rsa / ecb / pkcs1填充模式编码文本? - How to encode a text with rsa/ecb/pkcs1 padding mode with a given public key in java? 在Bouncy Castle中使用“ RSA / ECB / PKCS7Padding” - Using “RSA/ECB/PKCS7Padding” with Bouncy Castle RSA / NONE / PKCS1Padding给出错误,如java.security.NoSuchAlgorithmException - RSA/NONE/PKCS1Padding giving error as java.security.NoSuchAlgorithmException 如何在 Java 中使用 RSA_PKCS1_OAEP_PADDING 加密 - How to use RSA_PKCS1_OAEP_PADDING encrypt in Java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM