在 PHP 上删除长键,在 Java 上不删除
DESede long key on PHP, not in Java
我正在尝试将 Java 的 DESede
解密转换为 PHP 的版本。但是,对于相同的输入,PHP 无法提供相同的输出。
Java:
public class ThreeDES {
private KeySpec keySpec;
private SecretKeyFactory keyFactory;
private Cipher cipher;
public ThreeDES( String encryptionScheme, String encryptionKey )
throws EncryptionException {
try {
byte[] keyAsBytes = encryptionKey.getBytes("UTF-8");
keySpec = new DESedeKeySpec(keyAsBytes);
keyFactory = SecretKeyFactory.getInstance(encryptionScheme);
cipher = Cipher.getInstance(encryptionScheme);
} catch (InvalidKeyException e)
{
throw new EncryptionException( e );
}
catch (UnsupportedEncodingException e)
{
throw new EncryptionException( e );
}
catch (NoSuchAlgorithmException e)
{
throw new EncryptionException( e );
}
catch (NoSuchPaddingException e)
{
throw new EncryptionException( e );
}
}
public String decrypt( String encryptedString ) throws EncryptionException {
try {
SecretKey key = keyFactory.generateSecret( keySpec );
cipher.init( Cipher.DECRYPT_MODE, key );
BASE64Decoder base64decoder = new BASE64Decoder();
byte[] cleartext = base64decoder.decodeBuffer(encryptedString);
byte[] ciphertext = cipher.doFinal(cleartext);
return bytes2String( ciphertext );
}
catch (Exception e)
{
throw new EncryptionException( e );
}
}
private static String bytes2String( byte[] bytes )
{
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < bytes.length; i++)
{
stringBuffer.append( (char) bytes[i] );
}
return stringBuffer.toString();
}
}
PHP:
function decrypt($key, $data) {
$mcrypt_module = mcrypt_module_open(MCRYPT_TRIPLEDES, '', MCRYPT_MODE_ECB, '');
$mcrypt_iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($mcrypt_module), MCRYPT_RAND);
$decrypted = mcrypt_decrypt(MCRYPT_TRIPLEDES, $key, base64_encode($data), MCRYPT_MODE_ECB, $mcrypt_iv);
mcrypt_module_close($mcrypt_module);
return pkcs5_unpad($decrypted);
}
function pkcs5_unpad($text) {
$pad = ord($text{strlen($text)-1});
if ($pad > strlen($text)) return false;
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
return substr($text, 0, -1 * $pad);
}
给定以下输入参数,PHP 无法提供相同的输出:
$key = 'ASDFasdf12348983jklasdfJ2Jaf8';
$encrypted_data = 'cPap7+JIPS4=';
应解密为:
coRef=3
Java的测试代码如下:
try {
String encryptedStr = encrypted_data; // same value as PHP's $encrypted_data
String decryptedString = "";
ThreeDES desedeEncrypter = new ThreeDES("DSEede", key); // same value as PHP's $key
decryptedString = desedeEncrypter.decrypt(encryptedStr);
System.out.println(decryptedString);
} catch (ThreeDES.EncryptionException e) {
e.printStackTrace();
}
输出:coRef=3
。但是,以下 PHP 代码会引发有关密钥长度的警告。
echo decrypt($key, $encrypted_data);
Key of size 29 not supported by this algorithm. Only keys of size 24 supported in...
如何修改我的代码以使用超过 24 个字符的密钥?
嗯,这很奇怪,
Triple Des 只接受 24 个字节作为键
Each DES key is nominally stored or transmitted as 8 bytes, each of
odd parity,[12] so a key bundle requires 24 bytes for option 1, 16 for
option 2, or 8 for option 3.
所以我认为问题出在here
DESedeKeySpec
对象:
/**
* Uses the first 24 bytes in <code>key</code> as the DES-EDE key.
* <p>
* The bytes that constitute the DES-EDE key are those between
* <code>key[0]</code> and <code>key[23]</code> inclusive
*
* @param key the buffer with the DES-EDE key material.
* @exception InvalidKeyException if the given key material is shorter
* than 24 bytes.
*/
所以我认为 DESedeKeySpec
是将长度为 29 的密钥修剪为 24 以符合 tribledes
要求。
编辑 另一个重要说明 mcrypt_* 扩展已被弃用。
This function has been DEPRECATED as of PHP 7.1.0. Relying on this
function is highly discouraged.
我正在尝试将 Java 的 DESede
解密转换为 PHP 的版本。但是,对于相同的输入,PHP 无法提供相同的输出。
Java:
public class ThreeDES {
private KeySpec keySpec;
private SecretKeyFactory keyFactory;
private Cipher cipher;
public ThreeDES( String encryptionScheme, String encryptionKey )
throws EncryptionException {
try {
byte[] keyAsBytes = encryptionKey.getBytes("UTF-8");
keySpec = new DESedeKeySpec(keyAsBytes);
keyFactory = SecretKeyFactory.getInstance(encryptionScheme);
cipher = Cipher.getInstance(encryptionScheme);
} catch (InvalidKeyException e)
{
throw new EncryptionException( e );
}
catch (UnsupportedEncodingException e)
{
throw new EncryptionException( e );
}
catch (NoSuchAlgorithmException e)
{
throw new EncryptionException( e );
}
catch (NoSuchPaddingException e)
{
throw new EncryptionException( e );
}
}
public String decrypt( String encryptedString ) throws EncryptionException {
try {
SecretKey key = keyFactory.generateSecret( keySpec );
cipher.init( Cipher.DECRYPT_MODE, key );
BASE64Decoder base64decoder = new BASE64Decoder();
byte[] cleartext = base64decoder.decodeBuffer(encryptedString);
byte[] ciphertext = cipher.doFinal(cleartext);
return bytes2String( ciphertext );
}
catch (Exception e)
{
throw new EncryptionException( e );
}
}
private static String bytes2String( byte[] bytes )
{
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < bytes.length; i++)
{
stringBuffer.append( (char) bytes[i] );
}
return stringBuffer.toString();
}
}
PHP:
function decrypt($key, $data) {
$mcrypt_module = mcrypt_module_open(MCRYPT_TRIPLEDES, '', MCRYPT_MODE_ECB, '');
$mcrypt_iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($mcrypt_module), MCRYPT_RAND);
$decrypted = mcrypt_decrypt(MCRYPT_TRIPLEDES, $key, base64_encode($data), MCRYPT_MODE_ECB, $mcrypt_iv);
mcrypt_module_close($mcrypt_module);
return pkcs5_unpad($decrypted);
}
function pkcs5_unpad($text) {
$pad = ord($text{strlen($text)-1});
if ($pad > strlen($text)) return false;
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
return substr($text, 0, -1 * $pad);
}
给定以下输入参数,PHP 无法提供相同的输出:
$key = 'ASDFasdf12348983jklasdfJ2Jaf8';
$encrypted_data = 'cPap7+JIPS4=';
应解密为:
coRef=3
Java的测试代码如下:
try {
String encryptedStr = encrypted_data; // same value as PHP's $encrypted_data
String decryptedString = "";
ThreeDES desedeEncrypter = new ThreeDES("DSEede", key); // same value as PHP's $key
decryptedString = desedeEncrypter.decrypt(encryptedStr);
System.out.println(decryptedString);
} catch (ThreeDES.EncryptionException e) {
e.printStackTrace();
}
输出:coRef=3
。但是,以下 PHP 代码会引发有关密钥长度的警告。
echo decrypt($key, $encrypted_data);
Key of size 29 not supported by this algorithm. Only keys of size 24 supported in...
如何修改我的代码以使用超过 24 个字符的密钥?
嗯,这很奇怪,
Triple Des 只接受 24 个字节作为键
Each DES key is nominally stored or transmitted as 8 bytes, each of odd parity,[12] so a key bundle requires 24 bytes for option 1, 16 for option 2, or 8 for option 3.
所以我认为问题出在here
DESedeKeySpec
对象:
/**
* Uses the first 24 bytes in <code>key</code> as the DES-EDE key.
* <p>
* The bytes that constitute the DES-EDE key are those between
* <code>key[0]</code> and <code>key[23]</code> inclusive
*
* @param key the buffer with the DES-EDE key material.
* @exception InvalidKeyException if the given key material is shorter
* than 24 bytes.
*/
所以我认为 DESedeKeySpec
是将长度为 29 的密钥修剪为 24 以符合 tribledes
要求。
编辑 另一个重要说明 mcrypt_* 扩展已被弃用。
This function has been DEPRECATED as of PHP 7.1.0. Relying on this function is highly discouraged.