我正在尝试创建一个可以加密用户消息的应用。用户公钥需要作为字符串发布到服务器。我正在生成Android KyeStore PublicKey:
public static PublicKey getOrCreatePublicKey(String alias) throws GeneralSecurityException, IOException {
KeyStore keyStore = KeyStore.getInstance(ANDROID_PROVIDER);
keyStore.load(null);
if (!keyStore.containsAlias(alias) || keyStore.getCertificate(alias) == null) {
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
alias,
KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
.setDigests(KeyProperties.DIGEST_SHA256,
KeyProperties.DIGEST_SHA512)
.build();
KeyPairGenerator generator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, ANDROID_PROVIDER);
generator.initialize(spec);
generator.generateKeyPair();
}
return keyStore.getCertificate(alias).getPublicKey();
}
然后我尝试将PublicKey转换为字符串并返回到PublicKey,如下所示:
public static PublicKey stringToPublicKey(String publStr) {
PublicKey publicKey = null;
try {
byte[] data = Base64.decode(publStr, Base64.DEFAULT);
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance("RSA");
publicKey = fact.generatePublic(spec);
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
return publicKey;
}
public static String publicKeyToString(PublicKey publ) {
String publicKeyString = null;
try {
KeyFactory fact = KeyFactory.getInstance("RSA");
X509EncodedKeySpec spec = fact.getKeySpec(publ,
X509EncodedKeySpec.class);
publicKeyString = Base64.encodeToString(spec.getEncoded(), Base64.DEFAULT);
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
return publicKeyString;
}
然后我尝试使用公钥和私钥加密和解密用户消息。
如果我不转换公钥,加密工作正常。但是,如果我将公钥转换为字符串并返回公钥,则加密不再起作用。 我究竟做错了什么?谢谢。
PublicKey publicKey1 = getOrCreatePublicKey("alias");
String publicKeyStr = publicKeyToString(publicKey1);
PublicKey publicKey2 = stringToPublicKey(publicKeyStr);
//this one works
String message = encrypt(str, publicKey1);
String decryptm = decrypt(message, privateKey);
//this one doesn't work
String message = encrypt(str, publicKey2);
String decryptm = decrypt(message, privateKey);
答案 0 :(得分:0)
我已经取代了
<强> KeyProperties.ENCRYPTION_PADDING_RSA_OAEP 强> 同 的 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1 强>
我也已经取代了
Cipher cipher = Cipher.getInstance(&#34; RSA / ECB / OAEPWithSHA-256AndMGF1Padding&#34;);
与
Cipher cipher = Cipher.getInstance(&#34; RSA / ECB / PKCS1Padding&#34;);
现在它有效。但我仍然不知道为什么它第一次不起作用。
答案 1 :(得分:0)
您的publicKeyToString函数是完全错误的,不应该将stringToPublicKey的所有步骤都在“反向”中再次执行。我是说,是的,但是虽然从字符串再次构造密钥确实需要执行所有步骤,但将PublicKey转换为String基本上只需要一行。
public static String publicKeyToString(PublicKey publ) {
String publicKeyString = Base64.encodeToString(publ.getEncoded(), 2);
return publicKeyString;
}
这应该输出一个与您的stringToPublicKey函数一起使用的String(对我来说看起来正确)。