我必须解密一些数据发送到我的网站,使用aes-128-gcm加密与JAVA密码。
private static String encrypt(String data, String mainKey, int ivLength) throws Exception {
final byte[] dataBytes = data.getBytes(UNICODE_FORMAT);
byte[] initializationVector = generateInitializationVector(ivLength);
final Cipher cipher = getAesGcmCipher(Cipher.ENCRYPT_MODE, mainKey, initializationVector);
final byte[] encryptedData = cipher.doFinal(dataBytes);
final byte[] encryptedBytes = new byte[encryptedData.length + ivLength];
System.arraycopy(initializationVector, 0, encryptedBytes, 0, ivLength);
System.arraycopy(encryptedData, 0, encryptedBytes, ivLength, encryptedData.length);
return BASE64_ENCODER.apply(encryptedBytes);
}
private static String decrypt(String data, String mainKey, int ivLength) throws Exception {
final byte[] encryptedBytes = BASE64_DECODER.apply(data.getBytes(UNICODE_FORMAT));
final byte[] initializationVector = new byte[ivLength];
System.arraycopy(encryptedBytes, 0, initializationVector, 0, ivLength);
final Cipher cipher = getAesGcmCipher(Cipher.DECRYPT_MODE, mainKey, initializationVector);
return new String(cipher.doFinal(encryptedBytes, ivLength, encryptedBytes.length - ivLength),
UNICODE_FORMAT);
}
static final String ALGO = "AES"; //$NON-NLS-1$
static final String GCMALGO = "AES/GCM/NoPadding"; //$NON-NLS-1$
static final String UNICODE_FORMAT = "UTF8"; //$NON-NLS-1$
static final String DES_ENCRYPTION_SCHEME = "DES"; //$NON-NLS-1$
private static final int DEFAULT_IV_LENGTH = 16;
public static final String NULL_PARAMETER_MESSAGE = "The parameter should not be null"; //$NON-NLS-1$
public static final String EMPTY_PARAMETER_MESSAGE = "String is empty"; //$NON-NLS-1$
private static final String KEY_GEN_ALGO = "PBKDF2WithHmacSHA256"; //$NON-NLS-1$
static final Random random = new SecureRandom();
static final BASE64Encoder b64Encoder = new DataMasking().new BASE64Encoder();
static final BASE64Decoder b64Dencoder = new DataMasking().new BASE64Decoder();
public static final Function<byte[], String> BASE64_ENCODER = bytes -> Base64.getEncoder().encodeToString(bytes);
public static final Function<byte[], byte[]> BASE64_DECODER = bytes -> Base64.getDecoder().decode(bytes);
我想知道这是否与我必须对二进制数据进行的字符串操作有关,或者提供者没有给我所需的所有必要信息。
我也不知道解密数据必须使用的Tag_length是什么。提供程序还告诉我IV_Length是16个字符长,但是当我使用openssl_cipher_iv_length('aes-128-gcm')时,它建议是12个字符。
下面是我现在PHP端的代码:
/**
* @param string $str
* The URL parameter string
*/
function test_decrypt($str) {
$key = 'MySuperPassword7';
$cipher = 'aes-128-gcm';
$iv_len = 16;
$tag_length = 16;
echo $str . '<br>';
/**
* Encryption test
*/
// $tag = "";
// $iv = openssl_random_pseudo_bytes($iv_len);
// $enc_str = openssl_encrypt('Test of data to send', $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag, "", $tag_length);
// $encrypt = base64_encode($iv.$enc_str.$tag);
// echo $key . '::' . $iv . '::' . $tag . '<br>';
// echo '$enc_str<pre>';
// var_dump($enc_str);
// echo '</pre>';
// echo '$encrypt<pre>';
// var_dump($encrypt);
// echo '</pre>';
/**
* Decryption part
*/
$encrypt = base64_decode($str);
$iv = substr($encrypt, 0, $iv_len);
$tag = substr($encrypt, - $tag_length);
$ciphertext = substr($encrypt, $iv_len, -$tag_length);
$uncrypt = openssl_decrypt($ciphertext, $cipher, $key, 0, $iv, $tag);//OPENSSL_RAW_DATA + OPENSSL_NO_PADDING
echo $iv_len . '::' . $tag_length . '<br>';
echo $key . '::' . $iv . '::' . $tag . '<br>';
echo '$encrypt<pre>';
var_dump($encrypt);
echo '</pre>';
echo '$ciphertext<pre>';
var_dump($ciphertext);
echo '</pre>';
echo '$uncrypt<pre>';
var_dump($uncrypt);
echo '</pre>';
exit;
}
其长度与答案的加密长度相同(P8KU/GF27LU9QGMLPA8GPFHMDVUW5CC7XEKVIGMB3RGGZYJG0YHX5P/CFRROZPUXXTEKZJ8)。
像以前一样,我不能解密数据...
以下是Talend组件的完整代码:
// ============================================================================
//
// Copyright (C) 2006-2019 Talend Inc. - www.talend.com
//
// This source code is available under agreement available at
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
//
// You should have received a copy of the agreement
// along with this program; if not, write to Talend SA
// 9 rue Pages 92150 Suresnes, France
//
// ============================================================================
package routines;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PushbackInputStream;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.function.Function;
import java.util.stream.Stream;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
/**
* created by talend on 2016-04-08 Detailled comment.
*
*/
public class DataMasking {
static final String ALGO = "AES"; //$NON-NLS-1$
static final String GCMALGO = "AES/GCM/NoPadding"; //$NON-NLS-1$
static final String UNICODE_FORMAT = "UTF8"; //$NON-NLS-1$
static final String DES_ENCRYPTION_SCHEME = "DES"; //$NON-NLS-1$
private static final int DEFAULT_IV_LENGTH = 16;
public static final String NULL_PARAMETER_MESSAGE = "The parameter should not be null"; //$NON-NLS-1$
public static final String EMPTY_PARAMETER_MESSAGE = "String is empty"; //$NON-NLS-1$
private static final String KEY_GEN_ALGO = "PBKDF2WithHmacSHA256"; //$NON-NLS-1$
static final Random random = new SecureRandom();
static final BASE64Encoder b64Encoder = new DataMasking().new BASE64Encoder();
static final BASE64Decoder b64Dencoder = new DataMasking().new BASE64Decoder();
public static final Function<byte[], String> BASE64_ENCODER = bytes -> Base64.getEncoder().encodeToString(bytes);
public static final Function<byte[], byte[]> BASE64_DECODER = bytes -> Base64.getDecoder().decode(bytes);
public static class DataMaskingRoutineException extends RuntimeException {
private static final long serialVersionUID = -8622896150657449668L;
public DataMaskingRoutineException() {
super();
}
public DataMaskingRoutineException(String s) {
super(s);
}
public DataMaskingRoutineException(String s, Object o) {
super(s);
System.out.println(o);
}
}
/**
* Encrypt String: Encrypts a string using AES 128 .
* warning: this is not considered a secure function.
*
*
* {talendTypes} String
*
* {Category} Data Masking
*
* {param} String("foo") encryptString: The string to be encrypted.
*
* {param} byte[](new byte[] { 'T', 'a', 'l', 'e', 'n', 'd', 's', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' })
* keyValue: the
* key material of the secret key. The contents of the array are copied to protect against subsequent modification.
*
* {example} encryptAES("foo", new byte[] { 'T', 'a', 'l', 'e', 'n', 'd', 's', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' })
* result is UQ0VJZq5ymFkMYQeDrPi0A==
*
* @deprecated use {@link #encryptAESGCM(String, String, int)} instead of it
*
*/
@Deprecated
public static String encryptAES(String encryptString, byte[] keyValue) {
if (encryptString == null || keyValue == null) {
return NULL_PARAMETER_MESSAGE;
}
if (encryptString.length() == 0) {
return EMPTY_PARAMETER_MESSAGE;
}
try {
Key key = new SecretKeySpec(keyValue, ALGO);
Cipher cipher = Cipher.getInstance(ALGO);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = cipher.doFinal(encryptString.getBytes());
String encryptedValue = b64Encoder.encode(encVal);
return encryptedValue;
} catch (Exception e) {
throw new DataMaskingRoutineException(e.getMessage(), e);
}
}
/**
* Encrypt String: Encrypts a string using AES GCM 128 .
*
* {talendTypes} String
*
* {Category} Data Masking
*
* {param} String("foo") encryptString: The string to be encrypted.
*
* {param} String("TalendMainKey123") the main key used to encrypt the data.
*
* {example} encryptAESGCM("foo","TalendMainKey123") result could be
* +ngs4RohAx8OvInmioRwRYS0pymcNkQJCKqsdUPZqUZppN4= (but it should change from an execution to another).
*
*/
public static String encryptAESGCM(String encryptString, String mainKey) {
return encryptAESGCM(encryptString, mainKey, DEFAULT_IV_LENGTH);
}
/**
* Encrypt String: Encrypts a string using AES GCM 128 .
*
* {talendTypes} String
*
* {Category} Data Masking
*
* {param} String("foo") encryptString: The string to be encrypted.
*
* {param} String("TalendMainKey123") the main key used to encrypt the data.
*
* {param} int the length of initializationVector. must be one of 12/13/14/15/16.
*
* {example} encryptAESGCM("foo","TalendMainKey123",16) result could be
* +ngs4RohAx8OvInmioRwRYS0pymcNkQJCKqsdUPZqUZppN4= (but it should change from an execution to another).
*
*/
public static String encryptAESGCM(String encryptString, String mainKey, int ivLength) {
if (encryptString == null || mainKey == null) {
return NULL_PARAMETER_MESSAGE;
}
if (encryptString.length() == 0) {
return EMPTY_PARAMETER_MESSAGE;
}
try {
return encrypt(encryptString, mainKey, ivLength);
} catch (Exception e) {
throw new DataMaskingRoutineException(e.getMessage(), e);
}
}
/**
* decrypt String: Decrypts a string using AES 128.
* warning: this is not considered a secure function.
*
*
* {talendTypes} String
*
* {Category} Data Masking
*
* {param} String("UQ0VJZq5ymFkMYQeDrPi0A==") encryptedString: The string to be decrypted.
*
* {param} byte[](new byte[] { 'T', 'a', 'l', 'e', 'n', 'd', 's', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' })
* keyValue: the key material of the secret key. The contents of the array are copied to protect against subsequent
* modification.
*
* {example} decryptAES("UQ0VJZq5ymFkMYQeDrPi0A==",new byte[] { 'T', 'a', 'l', 'e', 'n', 'd', 's', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' })
* result is "foo"
*
* @deprecated use {@link #decryptAESGCM(String, String, int)} instead of it
*
*/
@Deprecated
public static String decryptAES(String encryptedString, byte[] keyValue) {
if (encryptedString == null || keyValue == null) {
return NULL_PARAMETER_MESSAGE;
}
if (encryptedString.length() == 0) {
return EMPTY_PARAMETER_MESSAGE;
}
try {
Key key = new SecretKeySpec(keyValue, ALGO);
Cipher cipher = Cipher.getInstance(ALGO);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = b64Dencoder.decodeBuffer(encryptedString);
byte[] decValue = cipher.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
} catch (Exception e) {
throw new DataMaskingRoutineException(e.getMessage(), e);
}
}
/**
* decrypt String: Decrypts a string using AES GCM 128.
*
* {talendTypes} String
*
* {Category} Data Masking
*
* {param} String("+ngs4RohAx8OvInmioRwRYS0pymcNkQJCKqsdUPZqUZppN4=") encryptedString: The string to be decrypted.
*
* {param} String("TalendMainKey123") the main key used to decrypt the data.
*
* {param} int the length of initializationVector. must be one of 12/13/14/15/16.
*
* {example} decryptAESGCM("+ngs4RohAx8OvInmioRwRYS0pymcNkQJCKqsdUPZqUZppN4=","TalendMainKey123",16) result
* is "foo"
*
*/
public static String decryptAESGCM(String encryptedString, String mainKey, int ivLength) {
if (encryptedString == null || mainKey == null) {
return NULL_PARAMETER_MESSAGE;
}
if (encryptedString.length() == 0) {
return EMPTY_PARAMETER_MESSAGE;
}
try {
return decrypt(encryptedString, mainKey, ivLength);
} catch (Exception e) {
throw new DataMaskingRoutineException(e.getMessage(), e);
}
}
/**
* decrypt String: Decrypts a string using AES GCM 128.
*
* {talendTypes} String
*
* {Category} Data Masking
*
* {param} String("+ngs4RohAx8OvInmioRwRYS0pymcNkQJCKqsdUPZqUZppN4=") encryptedString: The string to be decrypted.
*
* {param} String("TalendMainKey123") the main key used to decrypt the data.
*
* {example} decryptAESGCM("+ngs4RohAx8OvInmioRwRYS0pymcNkQJCKqsdUPZqUZppN4=","TalendMainKey123") result
* is "foo"
*
*/
public static String decryptAESGCM(String encryptedString, String mainKey) {
return decryptAESGCM(encryptedString, mainKey, DEFAULT_IV_LENGTH);
}
/**
* Encrypt String: Encrypts a string using DES .
* warning: this is not considered a secure function.
*
*
* {talendTypes} String
*
* {Category} Data Masking
*
* {param} String("foo") unencryptedString: The string to be encrypted.
*
* {param} String("ThisIsSecretEncryptionKey") myEncryptionKey: the string with the DES key material.
*
* {example} encryptDES("foo") result is DmNj+x2LUXA=
*
* @throws Exception
*/
public static String encryptDES(String unencryptedString, String myEncryptionKey) {
if (unencryptedString == null || myEncryptionKey == null) {
return NULL_PARAMETER_MESSAGE;
}
if (unencryptedString.length() == 0) {
return EMPTY_PARAMETER_MESSAGE;
}
try {
String encryptedString = null;
String myEncryptionScheme = DES_ENCRYPTION_SCHEME;
byte[] keyAsBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);
KeySpec myKeySpec = new DESKeySpec(keyAsBytes);
SecretKeyFactory mySecretKeyFactory = SecretKeyFactory.getInstance(myEncryptionScheme);
Cipher encipher = Cipher.getInstance(myEncryptionScheme);
SecretKey key = mySecretKeyFactory.generateSecret(myKeySpec);
encipher.init(Cipher.ENCRYPT_MODE, key);
byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT);
byte[] encryptedText = encipher.doFinal(plainText);
encryptedString = b64Encoder.encode(encryptedText);
return encryptedString;
} catch (Exception e) {
throw new DataMaskingRoutineException(e.getMessage());
}
}
/**
* Decrypt String: Decrypts a string using DES .
* warning: this is not considered a secure function.
*
*
* {talendTypes} String
*
* {Category} Data Masking
*
* {param} String("DmNj+x2LUXA=") encryptedString: the string with the DES key material.
*
* {param} String("ThisIsSecretEncryptionKey") myDecryptionKey: The string to be encrypted.
*
* {example} decryptDES("DmNj+x2LUXA=") result is "foo"
*
*/
public static String decryptDES(String encryptedString, String myDecryptionKey) {
if (encryptedString == null || myDecryptionKey == null) {
return NULL_PARAMETER_MESSAGE;
}
if (encryptedString.length() == 0) {
return EMPTY_PARAMETER_MESSAGE;
}
try {
String decryptedText = null;
String myDecryptionScheme = DES_ENCRYPTION_SCHEME;
byte[] keyAsBytes = myDecryptionKey.getBytes(UNICODE_FORMAT);
KeySpec myKeySpec = new DESKeySpec(keyAsBytes);
Cipher decipher = Cipher.getInstance(myDecryptionScheme);
SecretKeyFactory mySecretKeyFactory = SecretKeyFactory.getInstance(myDecryptionScheme);
SecretKey key = mySecretKeyFactory.generateSecret(myKeySpec);
decipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedText = b64Dencoder.decodeBuffer(encryptedString);
byte[] plainText = decipher.doFinal(encryptedText);
StringBuilder stringBuilder = new StringBuilder();
for (byte element : plainText) {
stringBuilder.append((char) element);
}
decryptedText = stringBuilder.toString();
return decryptedText;
} catch (Exception e) {
throw new DataMaskingRoutineException(e.getMessage(), e);
}
}
/**
* This method generates a secret Key using the key-stretching algorithm PBKDF2 of
* <a href="https://docs.oracle.com/javase/7/docs/api/javax/crypto/package-summary.html">javax.crypto</a>.
* It is basically a hashing algorithm slow by design, in order to increase the time
* required for an attacker to try a lot of passwords in a bruteforce attack.
* <br>
* About the salt :
* <ul>
* <li>The salt is not secret, the use of Random is not critical and ensure determinism.</li>
* <li>The salt is important to avoid rainbow table attacks.</li>
* <li>The salt should be generated with SecureRandom() in case the passwords are stored.</li>
* <li>In that case the salt should be stored in plaintext next to the password and a unique user identifier.</li>
* </ul>
*
* @param password a password given as a {@code String}.
* @param keyLength key length to generate
* @return a {@code SecretKey} securely generated.
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
private static byte[] generateSecretKeyFromPassword(String password, int keyLength)
throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] salt = new byte[keyLength];
new Random(password.hashCode()).nextBytes(salt);
SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_GEN_ALGO);
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, keyLength << 3);
return factory.generateSecret(spec).getEncoded();
}
private static String encrypt(String data, String mainKey, int ivLength) throws Exception {
final byte[] dataBytes = data.getBytes(UNICODE_FORMAT);
byte[] initializationVector = generateInitializationVector(ivLength);
final Cipher cipher = getAesGcmCipher(Cipher.ENCRYPT_MODE, mainKey, initializationVector);
final byte[] encryptedData = cipher.doFinal(dataBytes);
final byte[] encryptedBytes = new byte[encryptedData.length + ivLength];
System.arraycopy(initializationVector, 0, encryptedBytes, 0, ivLength);
System.arraycopy(encryptedData, 0, encryptedBytes, ivLength, encryptedData.length);
return BASE64_ENCODER.apply(encryptedBytes);
}
private static String decrypt(String data, String mainKey, int ivLength) throws Exception {
final byte[] encryptedBytes = BASE64_DECODER.apply(data.getBytes(UNICODE_FORMAT));
final byte[] initializationVector = new byte[ivLength];
System.arraycopy(encryptedBytes, 0, initializationVector, 0, ivLength);
final Cipher cipher = getAesGcmCipher(Cipher.DECRYPT_MODE, mainKey, initializationVector);
return new String(cipher.doFinal(encryptedBytes, ivLength, encryptedBytes.length - ivLength),
UNICODE_FORMAT);
}
}
private static Cipher getAesGcmCipher(int encryptMode, String mainKey, byte[] initializationVector)
throws Exception {
int ivLength = initializationVector.length;
if (Stream.of(12, 13, 14, 15, 16).noneMatch(i -> i == ivLength)) {
throw new IllegalArgumentException("Invalid IV length"); //$NON-NLS-1$
}
final Cipher cipher = Cipher.getInstance(GCMALGO);
SecretKey key = new SecretKeySpec(generateSecretKeyFromPassword(mainKey, mainKey.length()), ALGO);
final GCMParameterSpec spec = new GCMParameterSpec(ivLength * 8, initializationVector);
cipher.init(encryptMode, key, spec);
return cipher;
}
private static byte[] generateSecretKeyFromPassword(String password, int keyLength)
throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] salt = new byte[keyLength];
new Random(password.hashCode()).nextBytes(salt);
SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_GEN_ALGO);
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, keyLength << 3);
return factory.generateSecret(spec).getEncoded();
}
我在Java中设置代码,并使用(固定)密钥和随机初始化向量进行加密:
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Random;
public class SO_Main_Final {
static final String ALGO = "AES"; //$NON-NLS-1$
static final String GCMALGO = "AES/GCM/NoPadding"; //$NON-NLS-1$
static final String UNICODE_FORMAT = "UTF8"; //$NON-NLS-1$
static final Random random = new SecureRandom();
public static void main(String[] args) throws Exception {
System.out.println("https://stackoverflow.com/questions/62129604/decrypt-aes-128-gcm-encoded-content-with-java-cipher-using-php-openssl");
String myData = "Secret data for TytooF";
String myKey = "1234567890123456";
String encryptString = encrypt(myData, myKey, 16);
String decryptString = decrypt(encryptString, myKey, 16);
System.out.println("encryptString: " + encryptString);
System.out.println("decryptString: " + decryptString);
}
private static String encrypt(String data, String mainKey, int ivLength) throws Exception {
final byte[] dataBytes = data.getBytes(UNICODE_FORMAT);
// byte[] initializationVector = generateInitializationVector(ivLength);
byte[] initializationVector = new byte[ivLength];
random.nextBytes(initializationVector);
SecretKeySpec secretKeySpec = new SecretKeySpec(mainKey.getBytes(UNICODE_FORMAT), ALGO);
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, initializationVector);
Cipher cipher = Cipher.getInstance(GCMALGO);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, gcmParameterSpec);
final byte[] encryptedData = cipher.doFinal(dataBytes);
final byte[] encryptedBytes = new byte[encryptedData.length + ivLength];
System.arraycopy(initializationVector, 0, encryptedBytes, 0, ivLength);
System.arraycopy(encryptedData, 0, encryptedBytes, ivLength, encryptedData.length);
System.out.println("data [String] : " + data);
System.out.println("data length: " + dataBytes.length
+ " data: " + bytesToHex(dataBytes));
System.out.println("mainKey length: " + mainKey.getBytes(UNICODE_FORMAT).length
+ " data: " + bytesToHex(mainKey.getBytes(UNICODE_FORMAT)));
System.out.println("initvector length: " + initializationVector.length
+ " data: " + bytesToHex(initializationVector));
System.out.println("encryptedBytes length: " + encryptedBytes.length
+ " data: " + bytesToHex(encryptedBytes));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
private static String decrypt(String data, String mainKey, int ivLength) throws Exception {
final byte[] encryptedBytes = Base64.getDecoder().decode(data.getBytes(UNICODE_FORMAT));
final byte[] initializationVector = new byte[ivLength];
System.arraycopy(encryptedBytes, 0, initializationVector, 0, ivLength);
SecretKeySpec secretKeySpec = new SecretKeySpec(mainKey.getBytes(UNICODE_FORMAT), ALGO);
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, initializationVector);
Cipher cipher = Cipher.getInstance(GCMALGO);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, gcmParameterSpec);
return new String(cipher.doFinal(encryptedBytes, ivLength, encryptedBytes.length - ivLength),
UNICODE_FORMAT);
}
private static String bytesToHex(byte[] bytes) {
StringBuffer result = new StringBuffer();
for (byte b : bytes) result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
return result.toString();
}
}
最后,我得到了这样的结果--需要将“EncryptString”传输到您的网站:
https://stackoverflow.com/questions/62129604/decrypt-aes-128-gcm-encoded-content-with-java-cipher-using-php-openssl
data [String] : Secret data for TytooF
data length: 22 data: 536563726574206461746120666f72205479746f6f46
mainKey length: 16 data: 31323334353637383930313233343536
initvector length: 16 data: 3fc914fc67f6ecb53daa098ba40f20a5
encryptedBytes length: 54 data: 3fc914fc67f6ecb53daa098ba40f20a5f1e6755b96e5c0bb5de29522099bdeb806cf28c6d181d7e4ffdc15f451a19a54c714c42b38fc
encryptString: P8kU/Gf27LU9qgmLpA8gpfHmdVuW5cC7XeKVIgmb3rgGzyjG0YHX5P/cFfRRoZpUxxTEKzj8
decryptString: Secret data for TytooF
在WebServer/PHP端,我稍微修改了您的代码(“主要更改”是openssl_decrypt($ciphertext,$cipher,$key,true,$iv,$tag)一行的更改,因为我们不像以前的一些代码那样向decrypt方法提供base64编码的数据($encrypt=base64_decode($str)。
<?php
/**
* @param string $str
* The URL parameter string
*/
function test_decrypt($str)
{
$key = '1234567890123456';
$cipher = 'aes-128-gcm';
$iv_len = 16;
$tag_length = 16;
echo $str . '<br>';
/**
* Decryption part
*/
$encrypt = base64_decode($str);
$iv = substr($encrypt, 0, $iv_len);
$tag = substr($encrypt, -$tag_length);
$ciphertext = substr($encrypt, $iv_len, -$tag_length);
echo "" . "\n";
$value = unpack('H*', $iv);
echo '<br>iv:' . $value[1];
echo "" . "\n";
$value = unpack('H*', $ciphertext);
echo '<br>ciphertext:' . $value[1];
echo "" . "\n";
$value = unpack('H*', $tag);
echo '<br>tag:' . $value[1];
echo "<br>" . "\n";
$uncrypt = openssl_decrypt($ciphertext, $cipher, $key, true, $iv, $tag);//OPENSSL_RAW_DATA + OPENSSL_NO_PADDING
echo '<br>DecryptedString: ' . $uncrypt . "\n";
$value = unpack('H*', $uncrypt);
echo '<br>DecryptedString [byte[]]:' . $value[1];
exit;
}
echo '<b>Output for https://stackoverflow.com/questions/62129604/decrypt-aes-128-gcm-encoded-content-with-java-cipher-using-php-openssl</b><br>' . "\n";
echo '' . "\n";
echo 'Start decryption' . "\n";
$receivedData = "P8kU/Gf27LU9qgmLpA8gpfHmdVuW5cC7XeKVIgmb3rgGzyjG0YHX5P/cFfRRoZpUxxTEKzj8";
test_decrypt($receivedData);
?>
这是WebServer上的解密输出:
Output for https://stackoverflow.com/questions/62129604/decrypt-aes-128-gcm-encoded-content-with-java-cipher-using-php-openssl
Start decryption P8kU/Gf27LU9qgmLpA8gpfHmdVuW5cC7XeKVIgmb3rgGzyjG0YHX5P/cFfRRoZpUxxTEKzj8
iv:3fc914fc67f6ecb53daa098ba40f20a5
ciphertext:f1e6755b96e5c0bb5de29522099bdeb806cf28c6d181
tag:d7e4ffdc15f451a19a54c714c42b38fc
DecryptedString: Secret data for TytooF
DecryptedString [byte[]]:536563726574206461746120666f72205479746f6f46
2021年10月10日编辑:上面的代码使用的是长度为16字节的IV/nonce,但建议的IV/nonce长度为12。
我正在尝试在运行FreeRTOS的微处理器上使用mbedTLS加密一些文本。我正在使用带有PKCS7填充的AES 128 CBC。如果我尝试在mbedTLS中加密,并在文本少于16个字符时在Java中解密,则可以正常工作。我可以在Java中解密它,并且文本匹配。如果它更长,那么它就不再有效。我做错了什么? mbedTLS 代码: Java代码: Java抛出javax.crypto。BadPadd
尝试将数据解密为用AES-128加密的字节数组,使用字符串密钥"keykeykeykey1" 代码: 给我BadPaddingExc0019。我错过了什么?
本文向大家介绍java使用Hex编码解码实现Aes加密解密功能示例,包括了java使用Hex编码解码实现Aes加密解密功能示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了java使用Hex编码解码实现Aes加密解密功能。分享给大家供大家参考,具体如下: 这里的Aes加密解密方法使用Hex进行了编码解码 这个方法在正式的项目中已经在使用木有问题,注意这里的AES加密解密你要要对哦…… 上
我用Delphi加密“sifrelenecek”字符串,使用AES 128 ECB,使用密钥为“KRPTTT101103”,它给了我“FBE4A4405D6C1B54503D9B213E41AE56”,我正在检查http://aes.online-domain-tools.com/,它是正确的。我试图使用此功能创建相同的PHP加密; 但是php给我的结果是“wL2yf 72thixicjw0duQ
我用java编写了这段代码,以便解密密文。我有钥匙。对我来说,一切都是正确的,但我有我要解释的问题。 这是我的代码: 我收到以下错误: 出了什么问题?我知道这个问题在某种程度上与衬垫有关,但我不知道确切的解决方案。我只有一个密文IV和密钥。
节点模块: Java类:主要方法现在只是用于测试,稍后将被删除。