gpt4 book ai didi

java - Java 中的 AES 128 加密 PHP 中的解密

转载 作者:IT王子 更新时间:2023-10-28 23:55:04 27 4
gpt4 key购买 nike

我一直在尝试使用 AES-128 CBC 解密字符串,该字符串最初是使用 JAVA AES 加密进行加密的。在 java 中使用 PKCS7 填充。而且我尝试使用类似的 PHP 代码进行加密和解密。但我得到了不同的结果。

我的Java代码

import java.security.MessageDigest;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import android.util.Base64;

/**
* @author vipin.cb , vipin.cb@experionglobal.com <br>
* Sep 27, 2013, 5:18:34 PM <br>
* Package:- <b>com.veebow.util</b> <br>
* Project:- <b>Veebow</b>
* <p>
*/
public class AESCrypt {

private final Cipher cipher;
private final SecretKeySpec key;
private AlgorithmParameterSpec spec;
public static final String SEED_16_CHARACTER = "U1MjU1M0FDOUZ.Qz";

public AESCrypt() throws Exception {
// hash password with SHA-256 and crop the output to 128-bit for key
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(SEED_16_CHARACTER.getBytes("UTF-8"));
byte[] keyBytes = new byte[32];
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);

cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
key = new SecretKeySpec(keyBytes, "AES");
spec = getIV();
}

public AlgorithmParameterSpec getIV() {
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
IvParameterSpec ivParameterSpec;
ivParameterSpec = new IvParameterSpec(iv);

return ivParameterSpec;
}

public String encrypt(String plainText) throws Exception {
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
String encryptedText = new String(Base64.encode(encrypted,
Base64.DEFAULT), "UTF-8");

return encryptedText;
}

public String decrypt(String cryptedText) throws Exception {
cipher.init(Cipher.DECRYPT_MODE, key, spec);
byte[] bytes = Base64.decode(cryptedText, Base64.DEFAULT);
byte[] decrypted = cipher.doFinal(bytes);
String decryptedText = new String(decrypted, "UTF-8");

return decryptedText;
}

}

以及我正在使用的等效 PHP 代码。

<?php

class MCrypt {

private $iv = '0000000000000000'; #Same as in JAVA
private $key = 'U1MjU1M0FDOUZ.Qz'; #Same as in JAVA

function __construct() {
$this->key = hash('sha256', $this->key, true);
}

function encrypt($str) {
$iv = $this->iv;
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $this->key, $iv);
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return base64_encode($encrypted);
}

function decrypt($code) {
$iv = $this->iv;
$td = mcrypt_module_open('rijndael-128', '', 'cbc', '');
mcrypt_generic_init($td, $this->key, $iv);
$str = mdecrypt_generic($td, base64_decode($code));
$block = mcrypt_get_block_size('rijndael-128', 'cbc');
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $str;
//return $this->strippadding($str);
}

/*
For PKCS7 padding
*/
private function addpadding($string, $blocksize = 16) {
$len = strlen($string);
$pad = $blocksize - ($len % $blocksize);
$string .= str_repeat(chr($pad), $pad);
return $string;
}

private function strippadding($string) {
$slast = ord(substr($string, -1));
$slastc = chr($slast);
$pcheck = substr($string, -$slast);
if (preg_match("/$slastc{" . $slast . "}/", $string)) {
$string = substr($string, 0, strlen($string) - $slast);
return $string;
} else {
return false;
}
}

}

$encryption = new MCrypt();
echo $encryption->encrypt('123456') . "<br/>";
echo $encryption->decrypt('tpyxISJ83dqEs3uw8bN/+w==');

在Java中
纯文本 = 123456
密文=tpyxISJ83dqEs3uw8bN/+w==

在 PHP 中

纯文本 = 123456
密文=IErqfTCktrnmWndOpq3pnQ==

当我尝试使用 PHP 解密解密 Java 加密文本“tpyxISJ83dqEs3uw8bN/+w==”时,如果删除填充,我将得到一个空数组。在不删除填充的情况下,我得到 "::::::::::"

我认为 PHP 和 Java 中使用的 IV 字节有一些错误谁可以帮我这个事。我试过很多组合。还是没有结果。我对 Java 概念还很陌生。

-----解决方案--------

我已经根据owlstead 给出的评论修改了我的php 类。可能有更好的方法。我将它张贴在这里,以便将来有人会发现它有帮助,欢迎您提出意见以进一步改进。

<?php

class MCrypt {

private $hex_iv = '00000000000000000000000000000000'; # converted Java byte code in to HEX and placed it here
private $key = 'U1MjU1M0FDOUZ.Qz'; #Same as in JAVA

function __construct() {
$this->key = hash('sha256', $this->key, true);
//echo $this->key.'<br/>';
}

function encrypt($str) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $this->key, $this->hexToStr($this->hex_iv));
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return base64_encode($encrypted);
}

function decrypt($code) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $this->key, $this->hexToStr($this->hex_iv));
$str = mdecrypt_generic($td, base64_decode($code));
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $this->strippadding($str);
}

/*
For PKCS7 padding
*/

private function addpadding($string, $blocksize = 16) {
$len = strlen($string);
$pad = $blocksize - ($len % $blocksize);
$string .= str_repeat(chr($pad), $pad);
return $string;
}

private function strippadding($string) {
$slast = ord(substr($string, -1));
$slastc = chr($slast);
$pcheck = substr($string, -$slast);
if (preg_match("/$slastc{" . $slast . "}/", $string)) {
$string = substr($string, 0, strlen($string) - $slast);
return $string;
} else {
return false;
}
}
function hexToStr($hex)
{
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2)
{
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
}

$encryption = new MCrypt();
echo $encryption->encrypt('123456') . "<br/>";
echo $encryption->decrypt('tpyxISJ83dqEs3uw8bN/+w==');

最佳答案

您的 IV 不同,值为零的字节与字符 '0' 不同,字符 '0' 将转换为十六进制值为 30 或十进制值为 48 的字节(如果您假定使用 ASCII 或 UTF-8 编码)。

关于java - Java 中的 AES 128 加密 PHP 中的解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19196728/

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