【问题标题】:Getting this error when trying to encrypt. java.security.InvalidKeyException: unknown key type passed to RSA尝试加密时出现此错误。 java.security.InvalidKeyException:传递给 RSA 的未知密钥类型
【发布时间】:2023-03-23 09:53:01
【问题描述】:

我正在使用密钥对生成器来生成公钥和私钥。我想将公钥存储在 firebase 上。为此,我使用 getModulus 和 getExponent 并稍后重新生成公钥。当我重新生成密钥时,我得到完全相同的模数和指数,但在尝试加密时仍然出现此错误。

//This is my cryptography class
public class Cryptography {

    public static KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048, new SecureRandom());
        KeyPair pair = generator.generateKeyPair();
        return pair;
    }
    public static String encrypt1(String plainText, PublicKey publicKey) throws Exception {
        Cipher encryptCipher = Cipher.getInstance("RSA");

        encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);

        byte[] cipherText = encryptCipher.doFinal(plainText.getBytes("UTF-8"));
        String str = new String(cipherText, "UTF-8");

        return Base64.encodeToString(cipherText, Base64.NO_WRAP);
    }
    public static String decrypt1(String cipherText, PrivateKey privateKey) throws Exception {
        byte[] bytes = android.util.Base64.decode(cipherText, Base64.DEFAULT);

        Cipher decriptCipher = Cipher.getInstance("RSA");
        decriptCipher.init(Cipher.DECRYPT_MODE, privateKey);

        return new String(decriptCipher.doFinal(bytes), "UTF-8");
    }

    public static String sign(String plainText, PrivateKey privateKey) throws Exception {
        Signature privateSignature = Signature.getInstance("SHA256withRSA");
        privateSignature.initSign(privateKey);
        privateSignature.update(plainText.getBytes("UTF-8"));

        byte[] signature = privateSignature.sign();

        return Base64.encodeToString(signature, Base64.NO_WRAP);
    }

    public static boolean verify(String plainText, String signature, PublicKey publicKey) throws Exception {
        Signature publicSignature = Signature.getInstance("SHA256withRSA");
        publicSignature.initVerify(publicKey);
        publicSignature.update(plainText.getBytes("UTF-8"));

        byte[] signatureBytes = android.util.Base64.decode(signature, Base64.DEFAULT);

        return publicSignature.verify(signatureBytes);
    }
}




//Generate  keypair
    try {
      keyPair =  Cryptography.generateKeyPair();
        } catch (Exception e) {
             e.printStackTrace();
          }
          KeyFactory factory = null;
                    try {
                        factory = KeyFactory.getInstance("RSA");
                    } catch (NoSuchAlgorithmException e) {
                        e.printStackTrace();
                    }
                    RSAPublicKeySpec pub = null;
                    RSAPrivateKeySpec priv = null;
                    try {
                         pub = factory.getKeySpec(keyPair.getPublic(), RSAPublicKeySpec.class);
                         Log.e("PublicKey", pub.getModulus() + "\n" + pub.getPublicExponent());
                         priv = factory.getKeySpec(keyPair.getPrivate(), RSAPrivateKeySpec.class);
                    } catch (InvalidKeySpecException e) {
                        e.printStackTrace();
                    }
registerUser(display_name, email, password,Publicmod.toString(), Publicexpon.toString());


 // Retrieving the Modulus and Exponent and regenerating the publicKey

 String expo = getIntent().getStringExtra("expo");
        String mod = getIntent().getStringExtra("mod");
        Log.e("mod", mod);
        Log.e("expo", expo);

        BigInteger PublicExponent = new BigInteger(expo,16);
        BigInteger PublicMod = new BigInteger(mod,16);

        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(PublicMod, PublicExponent);
        KeyFactory fact = null;
        try {
            fact = KeyFactory.getInstance("RSA");

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        PublicKey pubKey = null;
        try {
            pubKey = fact.generatePublic(keySpec);
            Log.e("Public Key", pubKey.toString());
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        Log.e("Public Key", pubKey.toString());

【问题讨论】:

  • 请阅读“如何创建minimal reproducible example”。然后使用edit 链接改进您的问题(不要通过 cmets 添加更多信息)。否则我们无法回答您的问题并为您提供帮助。含义:不要你正在做什么来解决错误。给我们示例代码(带有示例数据)向我们展示会发生什么。如果您对代码性质的假设和解释是准确的,那么您就不会在这里想知道为什么某处存在错误...
  • 您应该对加密操作中的原始字节进行 base64 编码。在编码之前将其转换为字符串已经是有损的。

标签: java android firebase cryptography rsa


【解决方案1】:

我跑了

public static KeyPair generateKeyPair() throws NoSuchAlgorithmException
    {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048, new SecureRandom());
        return generator.generateKeyPair();
    }

    public static void main(String[] args) throws Exception
    {
        //Generate  keypair
        KeyPair keyPair = generateKeyPair();
        KeyFactory factory = KeyFactory.getInstance("RSA");
        RSAPublicKeySpec pub = factory.getKeySpec(keyPair.getPublic(), RSAPublicKeySpec.class);
        BigInteger PublicExponent = pub.getPublicExponent();
        BigInteger PublicMod = pub.getModulus();

        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(PublicMod, PublicExponent);

        KeyFactory fact = KeyFactory.getInstance("RSA");
        PublicKey pubKey = fact.generatePublic(keySpec);
        System.out.println("Success " + pubKey);
    }

其中打印了“Success ...”。

这意味着您的错误是对 expo 和 mod 的检索。 它们不能与您使用的相同。

还有几点说明:

  • 使用常量Charset.forName("UTF-8") 而不是将“UTF-8”放入getBytes
  • 生成KeyPair时不需要输入new SecureRandom
  • 如果您最终不使用字符串,请不要创建它
  • 如果您仍然可以访问数据,请不要检索数据

【讨论】:

    猜你喜欢
    • 2015-10-11
    • 1970-01-01
    • 2016-02-23
    • 1970-01-01
    • 1970-01-01
    • 2014-10-26
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多