当php中的密钥是整数时,java的解密密钥是什么



有一个现有的PHP系统(由另一家公司开发(,其加密代码如下。

$mopen = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', 'cfb', '');
mcrypt_generic_init($mopen, keygenerator(), $iv);
$cipherText = mcrypt_generic($mopen, $imageContent);

在上面的代码中,第二行,第二个参数是关键"keygenerator(("返回类型为介于10-99之间的int。

mcrypt_generic_init(资源$td,字符串$key,字符串$iv(:int

我必须使用java解密生成的文件。我使用的是bouncycastle库,我必须将密钥作为字节数组。如果";keygenerator(("生成32作为键。我怎么能在java中将其作为硬编码值。如果我使用以下代码。

String key = "32";
cipher.init(cryptoType, new ParametersWithIV(new KeyParameter(key.getBytes()), iv.trim().getBytes()));

它给了我以下错误。

线程中的异常"主";java.lang.IollegalArgumentException:密钥长度不是128/160/192/224/256位。

MCRYPT_RIJNDAEL_256支持16、24和32字节的密钥。如果密钥大小介于两者之间,则使用0值进行填充,直到达到下一个有效密钥长度
如果密钥长度是两位数,则下一个有效密钥大小为16字节,因此填充使用14个0值
这同样适用于IV,其长度必须与块大小相对应(Rijndael-256为32字节(。如果它更短,它也会填充0值(尽管这里通常会显示警告(
如果密钥太长(超过32个字节(,它将被截断。这同样适用于IV.

下面的PHP代码演示了这一点:

function encrypt($key, $iv){
$mopen = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', 'cfb', '');
mcrypt_generic_init($mopen, $key, $iv);
$cipherText = mcrypt_generic($mopen, "The quick brown fox jumps over the lazy dog");
print(base64_encode($cipherText) . "n");
}
$key = 32; // 0-padded to 16 bytes
$iv = 32;  // 0-padded to 32 bytes (Rijndael-256 blocksize), mostly a warning is displayed
encrypt($key, $iv); // Dgfd2xT2NQ1ULob3mOX+JBPQo57JUIxabtt+TX8wnzYWhKtt/6ltY2Z/yA==
$key = "32";
$iv = "32";
encrypt($key, $iv); // Dgfd2xT2NQ1ULob3mOX+JBPQo57JUIxabtt+TX8wnzYWhKtt/6ltY2Z/yA==
$key = "32";
$iv = "32";
encrypt($key, $iv); // Dgfd2xT2NQ1ULob3mOX+JBPQo57JUIxabtt+TX8wnzYWhKtt/6ltY2Z/yA==

在Java代码中,必须指定精确的键和IV大小。请注意,CFB是一种流密码模式,因此不使用填充。PHP应用CFB-8(8位模式下的CFB(,必须在Java代码中相应地指定CFB-8。以下Java/BuncyCastle代码对密文进行解密:

import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.RijndaelEngine;
import org.bouncycastle.crypto.modes.CFBBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
...
String ciphertextB64 = "Dgfd2xT2NQ1ULob3mOX+JBPQo57JUIxabtt+TX8wnzYWhKtt/6ltY2Z/yA==";
byte[] ciphertext = Base64.getDecoder().decode(ciphertextB64);
byte[] key = "32".getBytes(StandardCharsets.UTF_8);         
byte[] iv = "32".getBytes(StandardCharsets.UTF_8);     
BufferedBlockCipher bufferedBlockCipher = new BufferedBlockCipher(new CFBBlockCipher(new RijndaelEngine(256), 8)); // CFB in 8 bit mode
CipherParameters cipherParams = new ParametersWithIV(new KeyParameter(key), iv);
bufferedBlockCipher.init(false, cipherParams);        
byte[] decryptedBuffer = new byte[bufferedBlockCipher.getOutputSize(ciphertext.length)];
int processed = bufferedBlockCipher.processBytes(ciphertext, 0, ciphertext.length, decryptedBuffer, 0);
processed += bufferedBlockCipher.doFinal(decryptedBuffer, processed);
System.out.println(new String(decryptedBuffer, 0, processed, StandardCharsets.UTF_8)); // The quick brown fox jumps over the lazy dog      

我接受Topaco的回答。但我提供钥匙的方式没有什么不同。

String key = "33320000000000000000000000000000";
byte[] byteKey = new BigInteger(key,16).toByteArray();
cipher.init(cryptoType, new ParametersWithIV(new KeyParameter(byteKey), iv.trim().getBytes()));

最新更新