我想在PHP服务器和Java客户端之间加密数据。单独的代码工作正常,我想在PHP服务器上坚持使用OpenSSL。
你们中有人看到我在这里遗漏的东西吗?因为我在尝试解码PHP加密字符串时出错:
PHP:
<?php
$iv = 'fedcba9876543210'; #Same as in JAVA
$key = '0123456789abcdef'; #Same as in JAVA
$ciphers = openssl_get_cipher_methods(FALSE);
$ciphers_and_aliases = openssl_get_cipher_methods(true);
$cipher_aliases = array_diff($ciphers_and_aliases, $ciphers);
print_r($ciphers);
//print_r($cipher_aliases);
// DEFINE our cipher
define('AES_CBC', 'aes-128-cbc');
// Generate a 256-bit encryption key
// This should be stored somewhere instead of recreating it each time
$encryption_key = "test_key";
// Generate an initialization vector
// This *MUST* be available for decryption as well
//$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(AES_CBC));
// Create some data to encrypt
$data = "Hello World!!!";
$data_b64= base64_encode($data);
echo "Before encryption: $data<br><br>Before Base64: $data_b64<br><br>";
// Encrypt $data using aes-256-cbc cipher with the given encryption key and
// our initialization vector. The 0 gives us the default options, but can
// be changed to OPENSSL_RAW_DATA or OPENSSL_ZERO_PADDING
$encrypted = openssl_encrypt($data_b64, AES_CBC, $encryption_key, 0, $iv);
$len = strlen($encrypted);
echo "Encrypted Len: $len <br><br>";
$encrypted64 = base64_encode($encrypted);
echo "Encrypted b64: $encrypted64<br><br>";
// If we lose the $iv variable, we can't decrypt this, so:
// - $encrypted is already base64-encoded from openssl_encrypt
// - Append a separator that we know won't exist in base64, ":"
// - And then append a base64-encoded $iv
$encrypted = $encrypted64 . ':' . base64_encode($iv);
echo "Encrypted: $encrypted<br><br>";
// To decrypt, separate the encrypted data from the initialization vector ($iv).
$parts = explode(':', $encrypted);
// $parts[0] = encrypted data
// $parts[1] = base-64 encoded initialization vector
// Don't forget to base64-decode the $iv before feeding it back to
//openssl_decrypt
$decrypted64 = openssl_decrypt(base64_decode($parts[0]), AES_CBC, $encryption_key, 0, base64_decode($parts[1]));
$decrypted = base64_decode($decrypted64);
echo "Decrypted: $decrypted\n";
?>
字符串
PHP输出:
您好,世界!
Base64之前:SGVsbG 8 gV 29 ybGQhISE =
加密长度:44
加密b64:U21 yMVRGQTdROVc 3 TWJ 1 Wm 1HUTBhMmZmenlIN 2 tvdWQ 5SHA 5ekrampUmp 5az 0 =
加密:U21 yMVRGQTdROVc 3 TWJ 1 Wm 1HUTBhMmZmenlIN 2 tvdWQ 5SHA 5ekanderUmp 5az 0 =:ZmVkY 2 JhOTg 3 NjU 0 MzIxMA ==
您好,世界!
Java代码:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.security.*;
public class Sandbox {
public static String encrypt(String key, String initVector, String value) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(Base64.getEncoder().encode(value.getBytes()));
System.out.println("encrypted string: "
+ Base64.getEncoder().encodeToString(encrypted));
return Base64.getEncoder().encodeToString(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String decrypt(String key, String initVector, String encrypted) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] temp = Base64.getDecoder().decode(encrypted);
System.out.println((new String(temp)).length());
byte[] original = cipher.doFinal(temp);
original = Base64.getDecoder().decode(original);
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String key = "0123456789abcdef"; // 128 bit key
String initVector = "fedcba9876543210"; // 16 bytes IV
// for (Provider provider : Security.getProviders()) {
// System.out.println(provider.getName());
// for (String key2 : provider.stringPropertyNames()) {
// System.out.println("\t" + key2 + "\t" + provider.getProperty(key2));
// }
// }
System.out.println(decrypt(key, initVector,
encrypt(key, initVector, "Hello World!!!")));
System.out.println(decrypt(key, initVector, "R090NDcvclAyY2E1cmxLWG9kSGlnUktHdEI5U05sRGxNdWF4NFFjUUV0OD0="));
}
}
型
Java输出:
>
30
Hello World!!!
44
null
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:913)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at Sandbox.decrypt(Sandbox.java:43)
at Sandbox.main(Sandbox.java:67)
BUILD SUCCESSFUL (total time: 1 second)
型
5条答案
按热度按时间4dbbbstv1#
可以找到工作版本-https://github.com/chaudhuri-ab/CrossPlatformCiphers
需要记住的是,如果你没有在PHP中指定OPENSSL_RAW_DATA,数据将被加密为base64。
PHP:
字符串
Java:
型
fdbelqdn2#
我不明白为什么你的方法失败了。顺便说一下,我是这样做的,
** java **
字符串
PHP
型
Java输出
加密:PJG1Uu6SjJuuVGf7ApuHAw==
英文名:Arnab C
PHP输出
加密:PJG1Uu6SjJuuVGf7ApuHAw==
英文名:Arnab C
9q78igpj3#
我使用了theapache64的解决方案,但在PHP 7.2中,由于Mcrypt已被弃用并随后被删除,它停止工作。所以我更改了代码,它可以工作:
字符串
7cjasjjr4#
在我的情况下,我从谷歌请求“*java php aes加密 *”-或部分工作(本地),或根本没有工作。所以我收集了我在互联网上找到的一切,并作出了这一点,希望它有帮助。
注意事项:这个例子使用标准库,在两边,这就是为什么没有使用AES-256加密,不管PHP本机支持,因为Java不支持AES-256也不支持PKCS 7 Padding没有外部库,如Apache Crypto等。
PHP
字符串
Java:
型
发送到PHP可以这样做:
型
在PHP端接收和发送:
型
mpgws1up5#
在Java 8中,您不能使用
字符串
相反,您可以使用
型
然后,您还需要更改Base64.decode和Base64.encode行。
完整的代码如下所示(考虑到了petrnohejl关于PHP 7中已弃用的MSPOT的评论):
Java:
型
PHP:
型
不要给予我的学分,我只是信使,谁结合了几个职位。