gpt4 book ai didi

encryption - java.lang.IllegalArgumentException : bad base-64 when decrypting string

转载 作者:行者123 更新时间:2023-12-02 03:08:51 24 4
gpt4 key购买 nike

我正在尝试使用 KeyStore 加密字符串并使用这篇文章作为引用。

KeyPairGeneratorSpec replacement with KeyGenParameterSpec.Builder equivalents - Keystore operation failed

然而,当我解密字符串时,我不断收到这个“错误的 base-64”。我不明白如何解决这个问题。我知道加密的字符串包含解密器不知道的字符。但我不明白修复。

我看到了一些类似的帖子,但没有太大帮助,因为答案中没有代码。

java.lang.IllegalArgumentException: bad base-64

这是我的测试代码的片段,有人可以告诉我如何解密我的字符串吗?

Cipher inCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
inCipher.init(Cipher.ENCRYPT_MODE, publicKey);

Cipher outCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
outCipher.init(Cipher.DECRYPT_MODE, privateKey);

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(
outputStream, inCipher);
cipherOutputStream.write(plainText.getBytes("UTF-8"));
cipherOutputStream.close();

String ecryptedText = outputStream.toString();
Log.d(TAG, "Encrypt = " + ecryptedText);

String cipherText = ecryptedText;
CipherInputStream cipherInputStream = new CipherInputStream(
new ByteArrayInputStream(Base64.decode(cipherText, Base64.DEFAULT)), outCipher);
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();
}

String finalText = new String(bytes, 0, bytes.length, "UTF-8");
Log.d(TAG, "Decrypt = " + ecryptedText);

最佳答案

这是一个关于如何使用 Android KeyStore 的工作示例使用 ByteArrayOutputStream 加密/解密内存字符串和 ByteArrayInputStream .注意提供者更改,为 >= 6使用 "AndroidKeyStoreBCWorkaround"对于旧版本使用 "AndroidOpenSSL" .此外,您必须使用 Base64.encodeToString 将加密数据编码为 Base64 字符串。像这样:

String ecryptedText = Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT);

我的最终工作示例基于您的代码

try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
keyPairGenerator.initialize(
new KeyGenParameterSpec.Builder(
"key1",
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
.build());
KeyPair keyPair = keyPairGenerator.generateKeyPair();

// error in android 6: InvalidKeyException: Need RSA private or public key AndroidOpenSSL
// error in android 5: NoSuchProviderException: Provider not available: AndroidKeyStoreBCWorkaround
String provider = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? "AndroidOpenSSL" : "AndroidKeyStoreBCWorkaround";

Cipher inCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
inCipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());

Cipher outCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
outCipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(
outputStream, inCipher);

String plainText = "This is a text";

cipherOutputStream.write(plainText.getBytes("UTF-8"));
cipherOutputStream.close();

String ecryptedText = Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT);
Log.d(TAG, "Encrypt = " + ecryptedText);

String cipherText = ecryptedText;
CipherInputStream cipherInputStream = new CipherInputStream(
new ByteArrayInputStream(Base64.decode(cipherText, Base64.DEFAULT)), outCipher);

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();
}

String finalText = new String(bytes, 0, bytes.length, "UTF-8");
Log.d(TAG, "Decrypt = " + finalText);
} catch (javax.crypto.NoSuchPaddingException e) {
Log.e(TAG, Log.getStackTraceString(e));
} catch (IOException e) {
Log.e(TAG, Log.getStackTraceString(e));
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, Log.getStackTraceString(e));
} catch (NoSuchProviderException e) {
Log.e(TAG, Log.getStackTraceString(e));
} catch (InvalidAlgorithmParameterException e) {
Log.e(TAG, Log.getStackTraceString(e));
} catch (InvalidKeyException e) {
Log.e(TAG, Log.getStackTraceString(e));
} catch (UnsupportedOperationException e) {
Log.e(TAG, Log.getStackTraceString(e));
}

输出

D/MainActivity: Encrypt = rejkfeas3HgYnZOlC4S/R3KvlMTyiBjr5T6LqWGj9bq6nvpM0KBsoeYtr4OdCLITFX5GojuO4VpB
Hy11n8zc9JcAx4IFW0Aw0/DfCmMDvIomQItBAaIWewZqNHc0UwS0y/JRhAe8SiTz5sFJ6Abvgax6
vEfbYT0gzok+qtlfBNQLPvXejquhc0pZBaX1RgKDZyEJh3DBVRaFDgogK8XphaI/xtd1Cww9uO63
QxA7HfrFUN8rJXrHF4EMi/yrDxs2xVHGF0v21xeuXRwLW9JXYn4fFAJJ0Jr8N5f03UDuKeNlI568
RFVOGH7WpOLvKN4CDlsC+DT4Z8YVIOdtS/tO+Q==
D/MainActivity: Decrypt = This is a text

Android Studio Output

更新

对于 Android API 19,你只需要使用之前的 KeyStore API KeyPairGeneratorSpec而不是 KeyGenParameterSpec像这样:

try {
Calendar start = Calendar.getInstance();
Calendar end = Calendar.getInstance();
end.add(Calendar.YEAR, 1);

KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(this)
.setAlias("key1")
.setSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
.setSerialNumber(BigInteger.ONE)
.setStartDate(start.getTime())
.setEndDate(end.getTime())
.build();

KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
generator.initialize(spec);

// error in android 6: InvalidKeyException: Need RSA private or public key AndroidOpenSSL
// error in android 5: NoSuchProviderException: Provider not available: AndroidKeyStoreBCWorkaround
String provider = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? "AndroidOpenSSL" : "AndroidKeyStoreBCWorkaround";

KeyPair keyPair = generator.generateKeyPair();

Cipher inCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
inCipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());

Cipher outCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
outCipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());


ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(
outputStream, inCipher);

String plainText = "This is a text";

cipherOutputStream.write(plainText.getBytes("UTF-8"));
cipherOutputStream.close();

String ecryptedText = Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT);
Log.d(TAG, "Encrypt = " + ecryptedText);

String cipherText = ecryptedText;
CipherInputStream cipherInputStream = new CipherInputStream(
new ByteArrayInputStream(Base64.decode(cipherText, Base64.DEFAULT)), outCipher);

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();
}

String finalText = new String(bytes, 0, bytes.length, "UTF-8");
Log.d(TAG, "Decrypt = " + finalText);
} catch (javax.crypto.NoSuchPaddingException e) {
Log.e(TAG, Log.getStackTraceString(e));
} catch (IOException e) {
Log.e(TAG, Log.getStackTraceString(e));
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, Log.getStackTraceString(e));
} catch (NoSuchProviderException e) {
Log.e(TAG, Log.getStackTraceString(e));
} catch (InvalidAlgorithmParameterException e) {
Log.e(TAG, Log.getStackTraceString(e));
} catch (InvalidKeyException e) {
Log.e(TAG, Log.getStackTraceString(e));
} catch (UnsupportedOperationException e) {
Log.e(TAG, Log.getStackTraceString(e));
}

关于encryption - java.lang.IllegalArgumentException : bad base-64 when decrypting string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40987424/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com