PHP等效于PHP Triple DES ECB加密/解密
I have a below PHP function that I want to implement in Java with no luck, I'm not able to obtain the same output:
function encryptText( $plainText, $key )
{
$mcopen = mcrypt_module_open (MCRYPT_TripleDES, "", MCRYPT_MODE_ECB,"");
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size ($mcopen), MCRYPT_RAND);
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$cryptedHash = '';
if (mcrypt_generic_init($td, $key, $iv) != -1)
{
$cryptedHash = mcrypt_generic($td, $plainText);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
}
return base64_encode($cryptedHash);
}
This is my java code found here :
public static String encrypt(String message, String key) throws Exception {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest(key.getBytes("utf-8"));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey keyz = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keyz, iv);
final byte[] plainTextBytes = message.getBytes("utf-8");
final byte[] cipherText = cipher.doFinal(plainTextBytes);
final String encodedCipherText = new sun.misc.BASE64Encoder().encode(cipherText);
return encodedCipherText;
}
我有一个下面的PHP函数,我想用Java实现,没有运气,我无法获得 相同的输出: p>
function encryptText($ plainText,$ key)
{
$ mcopen = mcrypt_module_open(MCRYPT_TripleDES,“ “,MCRYPT_MODE_ECB,”“);
$ iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($ mcopen),MCRYPT_RAND);
$ td = mcrypt_module_open('tripledes','','ecb','');
$ cryptedHash ='';
if(mcrypt_generic_init($ td,$ key,$ iv)!= -1)
{
$ cryptedHash = mcrypt_generic($ td,$ plainText);
mcrypt_generic_deinit($ td) ;
mcrypt_module_close($ td);
}
返回base64_encode($ cryptedHash);
}
code> pre>
这是我找到的java代码这里: p>
public static String encrypt(String mes sage,String key)抛出异常{
最终MessageDigest md = MessageDigest.getInstance(“md5”);
final byte [] digestOfPassword = md.digest(key.getBytes(“utf-8”));
final byte [] keyBytes = Arrays.copyOf(digestOfPassword,24);
for(int j = 0,k = 16; j&lt; 8;){
keyBytes [k ++] = keyBytes [j ++];
}
最终的SecretKey keyz = new SecretKeySpec(keyBytes,“DESede”);
final IvParameterSpec iv = new IvParameterSpec(new byte [8 ]);
final Cipher cipher = Cipher.getInstance(“DESede / CBC / PKCS5Padding”);
cipher.init(Cipher.ENCRYPT_MODE,keyz,iv);
final byte [] plainTextBytes = message.getBytes (“utf-8”);
final byte [] cipherText = cipher.doFinal(plainTextBytes);
final String encodedCipherText = new sun.misc.BASE64Encoder()。encode(cipherText);
return encodedCipherText;
}
code> pre>
div>
Solved, the solution :
public static String cryptBC(String data, String key) throws Exception{
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] input = data.getBytes();
byte[] keyBytes = key.getBytes() ;
SecretKeySpec skey = new SecretKeySpec(keyBytes, "DESede");
Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding", "BC");
if(input.length % 8 != 0){
byte[] padded = new byte[input.length + 8 - (input.length % 8)];
System.arraycopy(input, 0, padded, 0, input.length);
input = padded;
}
System.out.println("input : " + new String(input));
cipher.init(Cipher.ENCRYPT_MODE, skey);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
return new String(Base64.encodeBase64(cipherText));
}
You have a couple of problems.
Since you want to use ECB mode, then you need to specify ECB mode. CBC is a different mode.
You're not running your key through MD5 in the PHP code, so you shouldn't do that in Java.
A block cipher in ECB or CBC mode needs a padding in order to encrypt arbitrary messages. Mcrypt uses zero padding by default, but you're specifying PKCS#5 padding in Java. Since the default Sun providers doesn't implement ZeroPadding, you will either need to implement it yourself by specifying "NoPadding" and implementing the zero padding yourself, or use the BouncyCastle provider:
Cipher.getInstance("DESede/ECB/ZeroPadding", "BC")
.
Other considerations:
Never use ECB mode. It's not semantically secure. If you encrypt the same message under the same key twice, the attacker can easily see that you encrypted the same message (or same part of the message) again.