在 Java 中加密并在 Postgres 中解密(使用 pgcrypto 模块)
Encrypting in Java and Decrypting in Postgres (using pgcrypto module)
我正在使用以下代码在 Java 中加密和解密,它似乎工作正常:
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.SecureRandom;
public class MainNew {
public static void main(String[] args) {
String iv = getEncryptionIV();
System.out.println(" iv = "+iv);
String encryptedData= encryptWithIVandKey(iv,encryptionKey,"rakesh.test@eltropy.com");
System.out.println(encryptedData);
String decryptedData = decrypt (iv,encryptionKey,encryptedData);
System.out.println(decryptedData);
}
static final String encryptionKey = "rakesh1@n1111111";
static byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(encryptMode, key, new IvParameterSpec(DatatypeConverter.parseHexBinary(iv)));
byte[] data = cipher.doFinal(bytes);
return data;
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return null;
}
static SecretKey generateKey(String passphrase) {
SecretKey key = null;
try {
key = new SecretKeySpec(passphrase.getBytes("UTF-8"), "AES");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return key;
}
static String getEncryptionIV() {
SecureRandom random = new SecureRandom();
byte[] ivBytes = new byte[16];
random.nextBytes(ivBytes);
return DatatypeConverter.printHexBinary(ivBytes);
}
static String encryptWithIVandKey( String iv, String passphrase, final String strToEncrypt) {
String encryptedStr = "";
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKey key = generateKey(passphrase);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(DatatypeConverter.parseHexBinary(iv)));
encryptedStr = DatatypeConverter.printBase64Binary(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return encryptedStr;
}
static String decrypt(String iv, String passphrase, String ciphertext) {
try {
SecretKey key = generateKey(passphrase);
byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, iv, DatatypeConverter.parseBase64Binary(ciphertext));
return new String(decrypted, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return "";
}
}
但是当我尝试在 postgres 中解密生成的加密数据时,出现错误:
select convert_from(decrypt_iv('IKMfAng499RNG9viRAreMM5Pmqooidkx76YUBflmzzs=', 'rakesh1@n1111111'::bytea, 'F700FE182F347120F1AE67F5B64E68C2'::bytea, 'aes-cbc/pad:pkcs'),'utf-8') res;
ERROR: decrypt_iv error: Data not a multiple of block size
当然,当您重新运行 Java class 时,您会得到一个新的 IV-- 因此,一个新的加密字符串。我认为您从上面注入到 PostgreSQL 示例中的 IV 和加密字符串已损坏。当我 运行 class 并获得新值时...
来自Java的输出:
iv = CE63BC477D1096B6F38CA77964CBD2CB
pl26CH0sNT8gycZe0FVSVUpwH/moMaFpa6zMtZHcBKQ=
rakesh.test@eltropy.com
但这不是真正的问题...您必须记住,您的加密字符串是以 base64 编码 字符串的形式出现的。为此使用 decode(text,text) 。然后 IV 作为 hex-encoded 字符串出现。也为此使用解码。
select convert_from(
decrypt_iv(
decode('pl26CH0sNT8gycZe0FVSVUpwH/moMaFpa6zMtZHcBKQ=','base64'),
'rakesh1@n1111111'::bytea,
decode('CE63BC477D1096B6F38CA77964CBD2CB','hex'), 'aes-cbc/pad:pkcs'),'utf-8') res;
我正在使用以下代码在 Java 中加密和解密,它似乎工作正常:
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.SecureRandom;
public class MainNew {
public static void main(String[] args) {
String iv = getEncryptionIV();
System.out.println(" iv = "+iv);
String encryptedData= encryptWithIVandKey(iv,encryptionKey,"rakesh.test@eltropy.com");
System.out.println(encryptedData);
String decryptedData = decrypt (iv,encryptionKey,encryptedData);
System.out.println(decryptedData);
}
static final String encryptionKey = "rakesh1@n1111111";
static byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(encryptMode, key, new IvParameterSpec(DatatypeConverter.parseHexBinary(iv)));
byte[] data = cipher.doFinal(bytes);
return data;
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return null;
}
static SecretKey generateKey(String passphrase) {
SecretKey key = null;
try {
key = new SecretKeySpec(passphrase.getBytes("UTF-8"), "AES");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return key;
}
static String getEncryptionIV() {
SecureRandom random = new SecureRandom();
byte[] ivBytes = new byte[16];
random.nextBytes(ivBytes);
return DatatypeConverter.printHexBinary(ivBytes);
}
static String encryptWithIVandKey( String iv, String passphrase, final String strToEncrypt) {
String encryptedStr = "";
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKey key = generateKey(passphrase);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(DatatypeConverter.parseHexBinary(iv)));
encryptedStr = DatatypeConverter.printBase64Binary(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return encryptedStr;
}
static String decrypt(String iv, String passphrase, String ciphertext) {
try {
SecretKey key = generateKey(passphrase);
byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, iv, DatatypeConverter.parseBase64Binary(ciphertext));
return new String(decrypted, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return "";
}
}
但是当我尝试在 postgres 中解密生成的加密数据时,出现错误:
select convert_from(decrypt_iv('IKMfAng499RNG9viRAreMM5Pmqooidkx76YUBflmzzs=', 'rakesh1@n1111111'::bytea, 'F700FE182F347120F1AE67F5B64E68C2'::bytea, 'aes-cbc/pad:pkcs'),'utf-8') res;
ERROR: decrypt_iv error: Data not a multiple of block size
当然,当您重新运行 Java class 时,您会得到一个新的 IV-- 因此,一个新的加密字符串。我认为您从上面注入到 PostgreSQL 示例中的 IV 和加密字符串已损坏。当我 运行 class 并获得新值时...
来自Java的输出:
iv = CE63BC477D1096B6F38CA77964CBD2CB
pl26CH0sNT8gycZe0FVSVUpwH/moMaFpa6zMtZHcBKQ=
rakesh.test@eltropy.com
但这不是真正的问题...您必须记住,您的加密字符串是以 base64 编码 字符串的形式出现的。为此使用 decode(text,text) 。然后 IV 作为 hex-encoded 字符串出现。也为此使用解码。
select convert_from(
decrypt_iv(
decode('pl26CH0sNT8gycZe0FVSVUpwH/moMaFpa6zMtZHcBKQ=','base64'),
'rakesh1@n1111111'::bytea,
decode('CE63BC477D1096B6F38CA77964CBD2CB','hex'), 'aes-cbc/pad:pkcs'),'utf-8') res;