Android RSA解密错误?
我尝试获取一对密钥(公共和私有)来加密/解密文本。 对于加密,没有问题。对于解密,我从一天起就犯了一个错误,我不明白为什么 这是代码的相关部分:Android RSA解密错误?,android,encryption,rsa,Android,Encryption,Rsa,我尝试获取一对密钥(公共和私有)来加密/解密文本。 对于加密,没有问题。对于解密,我从一天起就犯了一个错误,我不明白为什么 这是代码的相关部分: static void createKey(Context context) { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); Calendar start = Calendar.g
static void createKey(Context context) {
try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
Calendar start = Calendar.getInstance(Locale.ITALIAN);
Calendar end = Calendar.getInstance(Locale.ITALIAN);
end.add(Calendar.YEAR, 10);
AlgorithmParameterSpec spec = null;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
spec = new KeyPairGeneratorSpec.Builder(context)
.setAlias(BuildConfig.APPLICATION_ID)
.setSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
.setSerialNumber(BigInteger.ONE)
//.setStartDate(start.getTime())
//.setEndDate(end.getTime())
.build();
} else {
spec = new KeyGenParameterSpec.Builder(BuildConfig.APPLICATION_ID,KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setCertificateSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
.setDigests(KeyProperties.DIGEST_SHA256)
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
.setCertificateSerialNumber(BigInteger.valueOf(1337))
.setCertificateNotBefore(start.getTime())
.setCertificateNotAfter(end.getTime())
.setRandomizedEncryptionRequired(false)
.build();
}
kpg.initialize(spec);
KeyPair kp = kpg.generateKeyPair();
// END_INCLUDE(create_spec)
Log.d(TAG, "createKey Public Key is: " + kp.getPublic());
Log.d(TAG, "createKey Private Key is: " + kp.getPrivate());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
}
public static String encrypt(Context context, String text) {
if(text == null || text.isEmpty()) {
return null;
}
KeyStore keyStore = null;
try {
keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
PublicKey publicKey = keyStore.getCertificate(BuildConfig.APPLICATION_ID).getPublicKey();
Cipher input = getCipher();
input.init(Cipher.ENCRYPT_MODE, publicKey);//, ivspec);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(
outputStream, input);
cipherOutputStream.write(text.getBytes("UTF-8"));
cipherOutputStream.close();
byte [] vals = outputStream.toByteArray();
return Base64.encodeToString(vals, Base64.DEFAULT);
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
}
return null;
}
public static String decrypt(Context context, String encryptedText) {
KeyStore keyStore = null;
try {
keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
KeyStore.Entry entry = keyStore.getEntry(BuildConfig.APPLICATION_ID, null);
PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
PublicKey publicKey = keyStore.getCertificate(BuildConfig.APPLICATION_ID).getPublicKey();
Cipher output = getCipher();
output.init(Cipher.DECRYPT_MODE, privateKey);//, ivspec);
CipherInputStream cipherInputStream = new CipherInputStream(
new ByteArrayInputStream(Base64.decode(encryptedText, Base64.DEFAULT)), output);
ArrayList<Byte> values = new ArrayList<>();
int nextByte;
while ((nextByte = cipherInputStream.read()) != -1) {
values.add((byte)nextByte);
}
byte[] bytes = new byte[values.size()];
for(int i = 0; i < bytes.length; i++) {
bytes[i] = values.get(i).byteValue();
}
return new String(bytes, 0, bytes.length, "UTF-8");
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
}
return null;
}
static Cipher getCipher() throws Exception {
return Cipher.getInstance("RSA/ECB/PKCS1Padding");
}
您对此有什么想法吗?似乎每次都在创建密钥对。在创建密钥之前,请尝试检查密钥是否存在
if (!keyStore.containsAlias(ALIAS_RSA)) {
createKeys();
} else {
retrieveKeys();
}
包含完整的堆栈跟踪可能会有所帮助。还有,你在哪个版本的Android上遇到了这个错误?谢谢你的回复James,我已经编辑了我的问题,包括完整的堆栈跟踪。已经控制它了:if(!haveKey()){createKey(context);if(!haveKey())return null;}我已经检查了只在第一次调用createKey函数的情况,谢谢你的回复!看看setSignaturePaddings方法。它缝合它应该只用于签名/验证,而不是使用setEncryptionPaddings
if (!keyStore.containsAlias(ALIAS_RSA)) {
createKeys();
} else {
retrieveKeys();
}