gpt4 book ai didi

java - 安卓公钥加密

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:35:29 24 4
gpt4 key购买 nike

我的 Android 应用程序实现了 RSA 加密,但是后端无法解密应用程序生成的 token 。这是代码,在调用之前删除了公钥的开始和结束行,可能是什么问题?

String encryptedToken = Base64.encodeToString(encrypt(publicKey, "4111111111111111"), Base64.NO_WRAP);

public static byte[] encrypt(String publicKey, String data) {
if (TextUtils.isEmpty(publicKey) || TextUtils.isEmpty(data)) {
return null;
}
try {
// Decode the modified public key into a byte[]
byte[] publicKeyByteArray = Base64.decode(publicKey.getBytes("UTF-8"),Base64.NO_WRAP);

Cipher mCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyByteArray);
Key key = keyFactory.generatePublic(x509KeySpec);
mCipher.init(Cipher.ENCRYPT_MODE, key);
return mCipher.doFinal(data.getBytes("UTF-8"));
}
catch (UnsupportedEncodingException e) {
Log.e("RSAKEY", e.getMessage());
}
catch (NoSuchPaddingException e) {
Log.e("RSAKEY", e.getMessage());
} catch (NoSuchAlgorithmException e) {
Log.e("RSAKEY", e.getMessage());
} catch (InvalidKeyException e) {
Log.e("RSAKEY", e.getMessage());
} catch (InvalidKeySpecException e) {
Log.e("RSAKEY", e.getMessage());
} catch (IllegalBlockSizeException e) {
Log.e("RSAKEY", e.getMessage());
} catch (BadPaddingException e) {
Log.e("RSAKEY", e.getMessage());
}
return null;
}

后端团队提供了以下可用的示例代码,但它适用于桌面 java。 Android 库没有 Base64.getEncoder 方法。它与我写的非常相似,但我的就是行不通。

 // Decode the modified public key into a byte[]
byte[] publicKeyByteArray = Base64.getDecoder().decode(publicKey.getBytes(StandardCharsets.UTF_8));

// Create a PublicKey from the byte array
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyByteArray);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(keySpec);

// Get an instance of the Cipher and perform the encryption
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherText = cipher.doFinal(ccNum.getBytes(StandardCharsets.UTF_8));

// Get the encrypted value as a Base64-encoded String
String encodeToStr = Base64.getEncoder().encodeToString(cipherText);

// Print out the encoded, encrypted string
System.out.println("Encrypted and Encoded String: " + encodeToStr);

我在每一步都比较了字节数组值。桌面密码和安卓密码得到完全相同的输入。然而,Android代码cipher.doFinal的结果无法被后端解密。如果我将桌面结果放入 REST 调用主体,它们工作正常,所以这不是由 REST 调用引起的。

我还尝试在 Android 上创建一个公钥/私钥对,并使用生成的公钥进行加密,而不是使用来 self 们后端的公钥,并使用私钥解密,它可以正常工作。所以密码也有效,只是后端以某种方式期待不同的东西

最佳答案

团队中终于有人破解了这个问题。原因是因为Android操作系统使用Bouncy caSTLe,后端使用Sun作为提供者,导致后端抛出BadPaddingException。为了使其工作,需要在 Android 上以这种方式初始化密码:

 mCipher.init(Cipher.ENCRYPT_MODE, key, new
OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA1,
PSource.PSpecified.DEFAULT));

在这篇文章中查看更多详细信息: http://bouncy-castle.1462172.n4.nabble.com/Problems-with-OAEP-SHA-256-hash-crypto-td1466852.html

关于java - 安卓公钥加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46532454/

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