gpt4 book ai didi

java - 在 PHP 和 Java 之间使用 RSA 解密数据 Android 问题

转载 作者:太空宇宙 更新时间:2023-11-04 14:44:46 25 4
gpt4 key购买 nike

我正在使用 PHP 服务器加密一些数据,然后将其解密到 Android 设备。但是当我尝试在 Android 设备端解密它时,出现以下错误:

javax.crypto.BadPaddingException: error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02

当我在时

Cipher.getInstance("RSA/ECB/PKCS1Padding");

我正在使用 PHPSeclips 库(截至目前的最新 github 版本)对 PHP 服务器上的值进行加密并进行签名。这部分确实有效,因为已经用于在 Javacard 程序上进行解码,因此错误实际上不属于此处。

这是我在 Android 端进行的方式:

protected byte[] decryptData(String alias, byte[] data) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, BadPaddingException, IllegalBlockSizeException, UnsupportedOperationException {
Log.i(TAG, "decryptData() Decrypt data " + HexStringConverter.byteArrayToHexString(data));
byte[] decryptedData = null;
PrivateKey privateKey = getPrivateKey(alias);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
decryptedData = cipher.doFinal(data);
Log.i(TAG, "decryptData() Decrypted data: " + HexStringConverter.byteArrayToHexString(decryptedData));
return decryptedData;
}

使用 getPrivateKey() 方法:

protected RSAPrivateKey getPrivateKey(String alias) {
try {
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);
if (!(entry instanceof KeyStore.PrivateKeyEntry)) {
Log.w(TAG, "getPrivateKey() Not an instance of a PrivateKeyEntry");
}
return (RSAPrivateKey) ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
} catch (NoSuchAlgorithmException e) {
Log.w(TAG, "getPrivateKey() ", e);
} catch (KeyStoreException e) {
Log.w(TAG, "getPrivateKey() ", e);
} catch (CertificateException e) {
Log.w(TAG, "getPrivateKey() ", e);
} catch (IOException e) {
Log.w(TAG, "getPrivateKey() ", e);
} catch (UnrecoverableEntryException e) {
Log.w(TAG, "getPrivateKey() ", e);
}
return null;
}

以及 PHP 端如何加密:

//Function for encrypting with RSA
function rsa_encrypt($string, $key)
{
require_once(__DIR__ . '/../phpseclib/Crypt/RSA.php');
//Create an instance of the RSA cypher and load the key into it
$cipher = new Crypt_RSA();
$cipher->loadKey($key);
//Set the encryption mode
$cipher->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
//Return the encrypted version
return $cipher->encrypt($string);
}

//Function for decrypting with RSA
function rsa_sign($string, $key)
{
require_once(__DIR__ . '/../phpseclib/Crypt/RSA.php');
//Create an instance of the RSA cypher and load the key into it
$cipher = new Crypt_RSA();
$cipher->loadKey($key);
//Set the signature mode
$cipher->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);

//Return the signed message
return $cipher->sign($string);
}

更新(7/3/14)对于那些犯同样错误的人,我建议您查看以下页面:http://hustoknow.blogspot.ca/2013/01/rsa-block-type-is-not-02-error.html

事实上,这让我找到了发现问题所在的正确方法。

引发的错误表明解密 key 与用于加密它的 key 不匹配,因此我观察了用于此交换的每个公钥。因为我使用了 1024 key 大小,所以我正在解析输入消息(模数 + 公共(public)指数)以及每个消息的相关大小。我注意到,与 Android 设备上显示的模数相比,模数并未完全接收。所以这里有一个错误,当你使用 KeyPairGenerator 对象生成 key 时,Android 默认使用 2048 key 大小。只需手动将 key 大小设置为 1024 即可解决此问题。

示例:

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
Calendar notBefore = Calendar.getInstance();
Calendar notAfter = Calendar.getInstance();
notAfter.add(Calendar.YEAR, 1);
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(mContext)
.setAlias(alias)
.setKeySize(1024)
.setSubject(
new X500Principal(String.format("CN=%s, OU=%s", alias,
mContext.getPackageName())))
.setSerialNumber(BigInteger.ONE).setStartDate(notBefore.getTime())
.setEndDate(notAfter.getTime()).build();

keyPairGenerator.initialize(spec);
KeyPair kp = keyPairGenerator.generateKeyPair();

希望这有帮助。

最佳答案

您可能需要执行define('CRYPT_RSA_PKCS15_COMPAT', true)

以下评论 block 详细说明:

https://github.com/phpseclib/phpseclib/blob/a8c2ff0fb013169193c649adab512cafef5068cf/phpseclib/Crypt/RSA.php#L2272

基本上,OpenSSL(也可能是 Java)实现 PKCS#1 v1.5,而 phpseclib 实现 PKCS#1 v2.1。 PKCS#1 v2.1 修改了 PKCS1 样式加密以利用随机填充,因此不会有两个密文相同。

关于java - 在 PHP 和 Java 之间使用 RSA 解密数据 Android 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24541112/

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