当前位置: 首页 > 知识库问答 >
问题:

基于私钥的Android系统RSA解密

胡桐
2023-03-14
java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
public class AppUtils {


public static String encryptString(String value, Context context){
    byte[] encodedBytes = null;
    try {
        //Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE,  getPublicKey(context) );
        encodedBytes = cipher.doFinal(value.getBytes());
    } catch (Exception e) {
        e.printStackTrace();
    }

    return Base64.encodeToString(encodedBytes, Base64.DEFAULT);
}

public static String decryptString(String value, Context context){
    byte[] decodedBytes = null;
    try {
        //Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
        Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        c.init(Cipher.DECRYPT_MODE,  getPrivateKey(context) );
        decodedBytes = c.doFinal(Base64.decode(value, Base64.DEFAULT));
    } catch (Exception e) {
        e.printStackTrace();
    }

    return new String(decodedBytes);
}


public static PrivateKey getPrivateKey(Context context){

    // reads the key_public key stored in a file
    InputStream is = context.getResources().openRawResource(R.raw.key_private);
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    List<String> lines = new ArrayList<String>();
    String line = null;

    try {


        while ((line = br.readLine()) != null)
            lines.add(line);


        // removes the first and last lines of the file (comments)
        if (lines.size() > 1 && lines.get(0).startsWith("-----") && lines.get(lines.size()-1).startsWith("-----")) {
           lines.remove(0);
         lines.remove(lines.size()-1);
        }

        // concats the remaining lines to a single String
        StringBuilder sb = new StringBuilder();
        for (String aLine: lines)
            sb.append(aLine);
        String keyString = sb.toString();

        byte [] encoded = Base64.decode(keyString, Base64.DEFAULT);

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);

        PrivateKey myPrivKey = keyFactory.generatePrivate(keySpec);

        return myPrivKey;

    }catch (Exception e){

        e.printStackTrace();
    }
    return null;
}

public static PublicKey getPublicKey(Context context){

    // reads the key_public key stored in a file
    InputStream is = context.getResources().openRawResource(R.raw.key_public);
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    List<String> lines = new ArrayList<String>();
    String line = null;


    try {


        while ((line = br.readLine()) != null)
            lines.add(line);

        // removes the first and last lines of the file (comments)
        if (lines.size() > 1 && lines.get(0).startsWith("-----") && lines.get(lines.size()-1).startsWith("-----")) {
            lines.remove(0);
            lines.remove(lines.size()-1);
        }

        // concats the remaining lines to a single String
        StringBuilder sb = new StringBuilder();
        for (String aLine: lines)
            sb.append(aLine);
        String keyString = sb.toString();

        // converts the String to a PublicKey instance
        byte[] keyBytes = Base64.decode(keyString, Base64.DEFAULT);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey key = keyFactory.generatePublic(spec);

        return key;
    }catch (Exception e){
            e.printStackTrace();
    }

    return null;
}
}
String encryptedString =  AppUtils.encryptString("SHANKAR", MainActivity.this);

Log.d("DX1", " Encrypted String " + encryptedString );


String decryptedString =  AppUtils.decryptString(encryptedString, MainActivity.this);

Log.d("DX1", " decrypted String " + decryptedString );
PrivateKey myPrivKey = keyFactory.generatePrivate(keySpec);
-----BEGIN PUBLIC KEY-----
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgEac6cgM4Ch5vY2Rqvzw2ARaNEHv
PCbXWW1nPy3ft8CNFyLoIltwrnouY0azYECclONARh48qQUQ+UG62wNUtciLq9yX
3m0ePE7u/RYmNUnGWok6LMNZK1gGBu6TBnzNjDWi3CuR00xFzZ2TBtUMDowOa/+b
tfGTywGDLPJjgbtPAgMBAAE=
-----END PUBLIC KEY-----

我的私钥:

-----BEGIN RSA PRIVATE KEY-----
MIICWgIBAAKBgEac6cgM4Ch5vY2Rqvzw2ARaNEHvPCbXWW1nPy3ft8CNFyLoIltw
rnouY0azYECclONARh48qQUQ+UG62wNUtciLq9yX3m0ePE7u/RYmNUnGWok6LMNZ
K1gGBu6TBnzNjDWi3CuR00xFzZ2TBtUMDowOa/+btfGTywGDLPJjgbtPAgMBAAEC
gYAAxTd7ukA70NAzmjI+XjZNHdrSGVUTq2fLXMQAsR8lF6T3+YZebwVISfdFTzGu
osaxEANz0v+ZEY1WnT5EdAkjqwtYauj0tDnYmuciju2uVnEYLPOaOvpkmM7e9y+a
NWTvG/C0qAXtTT/EJgAwfCyrhuigyxzwUIyqhW2xgQ8MKQJBAIgM5xPKd30HU98t
jOHzouwSjsv5NIFOM9RnLPGA6HazQGu/0h2S27UnzaU8KKjln1X2q22GMa1cSvIL
q06e+MsCQQCE3oZudjOBgJaKtk7iETiIIoVVk3K1RMSGT/56SrglB1K1kNuFOpg+
obs+8j366gQk47ZgaIZwSRfro0VhTysNAkBiLEVWv6QHgZEhG6Jsrb1j8mQ+hd5A
bGj0HVuODYIxnVmgJvP8yStnhohbcpS4g7G9e1jqmIoiWdXu4ULFYeuPAkAIcKYz
cBi3ejaV2xzJqXRg2WiE1hfsQdEGAyDUHdjyqTNsyyXWobE4EUf2qKadQK5AtaJJ
H3qiuVHmqvlmRAQlAkB4Cl2nYBpK1IdusfwtjfaKppLa/r5k1D35cybxLn1uS3Xz
wwqRUuXrDkb4+TCD3B7Lkuym/kfFE2iIpANAVkeN
-----END RSA PRIVATE KEY-----

共有1个答案

池赞
2023-03-14

我也有同样的问题,试了几天想知道它是如何工作的,最后,我得到了它!

您的私钥不是PKCS#8格式。

PKCS8键以

转换应用程序中的私钥。为此,您需要将第三方库包含到项目中。

将这一行添加到您的应用程序梯度中

编译'com.madgag.spongycastle:core:1.56.0.0'

public static PrivateKey getPrivateKey(Context context) throws 
    GeneralSecurityException, IOException {
            InputStream is = context.getResources().openRawResource(R.raw.rsa_2048_priv);
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            List<String> lines = new ArrayList<String>();
            String line = null;

                while ((line = br.readLine()) != null)
                    lines.add(line);

                if (lines.size() > 1 && lines.get(0).startsWith("-----") && lines.get(lines.size() - 1).startsWith("-----")) {
                    lines.remove(0);
                    lines.remove(lines.size() - 1);
                }

                StringBuilder sb = new StringBuilder();
                for (String aLine : lines)
                    sb.append(aLine);
                String keyString = sb.toString();

                byte[] encodedPrivateKey = Base64.decode(keyString, Base64.DEFAULT);

                try {
                    ASN1Sequence primitive = (ASN1Sequence) ASN1Sequence
                            .fromByteArray(encodedPrivateKey);
                    Enumeration<?> e = primitive.getObjects();
                    BigInteger v = ((ASN1Integer) e.nextElement()).getValue();

                    int version = v.intValue();
                    if (version != 0 && version != 1) {
                        throw new IllegalArgumentException("wrong version for RSA private key");
                    }
                    /**
                     * In fact only modulus and private exponent are in use.
                     */
                    BigInteger modulus = ((ASN1Integer) e.nextElement()).getValue();
                    BigInteger publicExponent = ((ASN1Integer) e.nextElement()).getValue();
                    BigInteger privateExponent = ((ASN1Integer) e.nextElement()).getValue();

                    RSAPrivateKeySpec spec = new RSAPrivateKeySpec(modulus, privateExponent);
                    KeyFactory kf = KeyFactory.getInstance("RSA");
                    return kf.generatePrivate(spec);
                } catch (IOException e2) {
                    throw new IllegalStateException();
                } catch (NoSuchAlgorithmException e) {
                    throw new IllegalStateException(e);
                } catch (InvalidKeySpecException e) {
                    throw new IllegalStateException(e);
                }

        }

从PEM BASE64编码的私钥文件中获取RSA私钥

JAVA RSA解密不起作用,引发InvalidKeySpecException

将PEM传统私钥转换为PKCS8私钥

 类似资料:
  • 我从后端服务器得到一个加密的字符串,我需要使用Android中的私钥来解密。解密是有效的,但它在解密字符串的末尾附加了一个特殊的字符。下面是我正在使用的代码: 解密的字符串应该以“==”结尾。有人能帮我弄清楚,如何删除解密字符串结尾的特殊字符。 谢谢

  • 这是我的密码 抱歉,如果我的代码一团糟。

  • 本文向大家介绍基于私钥加密公钥解密的RSA算法C#实现方法,包括了基于私钥加密公钥解密的RSA算法C#实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了基于私钥加密公钥解密的RSA算法C#实现方法,是一种应用十分广泛的算法。分享给大家供大家参考之用。具体方法如下: 一、概述 RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。 RSA是被研究得最广泛的公钥算法,从提出

  • (我正在用MAC) 我的id_rsa以 但我希望一开始 我已将我的身份证发送给rsa。发布给服务器管理员以获得对服务器的访问权,因此我不想生成新密钥。 > 有什么方法可以将我的id_rsaopenssh私钥转移到RSA私钥吗?(请指挥。) 如果我可以传输,我是否还需要传输id_rsa。酒吧(请发命令。)看来是我的错。pub没有像id_rsa这样的头,所以我不确定是否也应该传输它。 非常感谢。

  • 我试图实现一个系统,其中a生成一个RSA密钥对,并将公钥发送给B。B然后生成一个AES密钥,并使用公钥对其进行加密,然后将结果发送回a。a然后使用其RSA私钥对AES密钥进行解密,使用AES密钥对数据进行加密并将其发送给B。B然后可以使用AES密钥对其进行解密。 最初,当使用RSA私钥解密AES密钥时,我得到了一个错误9809,这无助于转化为一个常规错误。对错误的研究指出,填充(我使用的是PKCS

  • 当我用OpenSSL生成RSA密钥对时,似乎私钥(私有指数)总是小于公钥(模)。它是由RSA设计的吗?

  • 我一直在搜索,但我似乎找不到一个简单的方法解密使用RSA。 我生成了一个公钥和私钥,它们存储在两个单独的文件中,并且是XML格式的。使用FromXmlString将公钥关联到RSACryptoServiceProvider对象,然后加密一个字符串,这一点没有问题。当我试图解密一个加密的字符串时,我的困惑就来了。我不确定如何将私钥数据与RSACryptoServiceProvider关联,以便使用D

  • 我在使用Java Bouncycastle的客户机和使用Python RSA库的密钥服务器之间交换私钥时遇到了困难。PEM格式用于通过REST传输密钥。keyserver无法解密我提供的密钥(加密密码更改时需要),它需要PKCS#1或PKCS#8密钥和PEM,如下所示: 但是BouncyCastle的输出(使用JCEpeEncryptorBuilder和JcaMiscPEMGenerator)的起