java - 尝试加密时出现此错误。java.security.InvalidKeyException:传递给 RSA 的未知密钥类型
问题描述
我正在使用密钥对生成器来生成公钥和私钥。我想将公钥存储在 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());
解决方案
我跑了
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);
}
其中印有“成功......”。
这意味着您的错误是对 expo 和 mod 的检索。它们不能与您使用的相同。
还有一些注意事项:
- 使用常量
Charset.forName("UTF-8")
而不是将“UTF-8”放入getBytes
new SecureRandom
生成时不需要放KeyPair
- 如果您最终不使用它,请不要创建字符串
- 如果您仍然可以访问数据,请不要检索数据
推荐阅读
- php - Codeigniter 欢迎页面未显示,而是显示乱码
- azure-blob-storage - 为什么会创建一个名为 Azure Blob 存储容器内文件夹名称的空文件?
- identityserver3 - 交换代码的无效客户端_identityserver3_AppAuth
- python - 将行值量化为组并计算每组的平均值
- stm32 - 操作期间图像转储失败
- printing - 将图像打印到 Zebra 打印机
- assembly - 只为“Hello World!”打印 H TI 84+ CE 组装程序
- java - Scala - 如何重构方法以使用 reduceLeft 而不是迭代?
- javascript - 输入类型文件超出其宽度
- azure - 在 Azure 上使用 Powershell 创建基于 vCore 的弹性池时出错