public static String encrypt(byte[] publicKey, byte[] data) throws IOException { if (publicKey == null || publicKey.length == 0) { return null; } if (data == null || data.length == 0) { return null; } byte[] source = new byte[data.length]; System.arraycopy(data, 0, source, 0, data.length); Cipher cipher = new Cipher(); SM2 sm2 = SM2.Instance(); ECPoint userKey = sm2.ecc_curve.decodePoint(publicKey); ECPoint c1 = cipher.Init_enc(sm2, userKey); cipher.Encrypt(source); byte[] c3 = new byte[32]; cipher.Dofinal(c3); return Util.byteToHex(c1.getEncoded()) + Util.byteToHex(source) + Util.byteToHex(c3); }
时间: 2024-04-10 11:30:25 浏览: 11
这段代码是一个使用 SM2 算法进行加密的方法。下面是对代码的解析:
1. 首先,对公钥(publicKey)和待加密数据(data)进行了非空判断,如果其中任何一个为空,则返回 null。
2. 接下来,创建了一个与待加密数据相同长度的字节数组 source,并将待加密数据复制到 source 中。这是为了保护原始数据,以便进行加密。
3. 创建了 Cipher 对象,并实例化 SM2 对象。
4. 使用 SM2 对象的 ecc_curve.decodePoint(publicKey) 方法将公钥解码为 ECPoint 对象 userKey。
5. 调用 cipher 对象的 Init_enc(sm2, userKey) 方法初始化加密操作,并返回 ECPoint 对象 c1。
6. 调用 cipher 对象的 Encrypt(source) 方法对源数据 source 进行加密操作。
7. 创建了一个长度为 32 的字节数组 c3。
8. 调用 cipher 对象的 Dofinal(c3) 方法,将加密结果存储到 c3 数组中。
9. 返回了经过编码后的加密结果,包括 c1、source 和 c3,使用 Util.byteToHex() 方法将字节数组转换为十六进制字符串。
请注意,由于代码中引用了一些未提供的自定义类和方法(如 Cipher、SM2、Util),因此无法完全了解代码的实际功能和正确性。如需更详细的解析,请提供相关类和方法的实现或更多上下文信息。
相关问题
postgresql通过pgp_sym_encrypt函数加密的数据如何用jdk11进行解密
要使用 JDK 11 进行解密 postgresql 中通过 `pgp_sym_encrypt` 函数加密的数据,需要进行以下步骤:
1. 获取加密后的数据
首先,需要从 postgresql 中获取使用 `pgp_sym_encrypt` 函数加密后的数据。可以使用以下 SQL 语句获取:
```
SELECT pgp_sym_encrypt('your_secret_data', 'your_secret_key');
```
将 `your_secret_data` 替换为需要加密的数据,将 `your_secret_key` 替换为加密所使用的密钥。
2. 导入 BouncyCastle 依赖
BouncyCastle 是一个开源的密码学库,它提供了加密、解密、签名等功能。JDK 11 中提供了对 BouncyCastle 的支持,但是需要手动导入相关的依赖。
在 pom.xml 文件中添加以下依赖:
```xml
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>
```
3. 解密数据
使用 JDK 11 和 BouncyCastle 库可以很容易地解密通过 `pgp_sym_encrypt` 函数加密的数据。以下是解密代码示例:
```java
import java.io.IOException;
import java.security.NoSuchProviderException;
import java.security.Security;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.modes.CFBBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class PgpSymmetricDecrypt {
public static void main(String[] args) throws NoSuchProviderException, IOException, InvalidCipherTextException {
Security.addProvider(new BouncyCastleProvider());
String encryptedData = "<your_encrypted_data>";
String secretKey = "<your_secret_key>";
byte[] encryptedBytes = encryptedData.getBytes();
byte[] keyBytes = secretKey.getBytes();
// Initialize cipher
AESFastEngine aesEngine = new AESFastEngine();
CFBBlockCipher cfbBlockCipher = new CFBBlockCipher(aesEngine, 128);
KeyParameter keyParameter = new KeyParameter(keyBytes);
cfbBlockCipher.init(false, keyParameter);
// Decrypt data
byte[] decryptedBytes = new byte[encryptedBytes.length];
int length = cfbBlockCipher.processBytes(encryptedBytes, 0, encryptedBytes.length, decryptedBytes, 0);
cfbBlockCipher.doFinal(decryptedBytes, length);
String decryptedData = new String(decryptedBytes);
System.out.println("Decrypted data: " + decryptedData);
}
}
```
将 `<your_encrypted_data>` 替换为从 postgresql 中获取到的加密数据,将 `<your_secret_key>` 替换为加密时使用的密钥。执行代码后,即可得到解密后的数据。
注意:在实际生产环境中,需要注意密钥的安全性,使用合适的加密算法和密钥长度。
使用 java 对文件进行pgp加密的完整工具类代码
下面是一个使用 BouncyCastle 实现 PGP 加密和解密的 Java 工具类示例:
```java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Date;
import java.util.Iterator;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.bcpg.sig.Features;
import org.bouncycastle.bcpg.sig.KeyFlags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPObjectFactory;
import org.bouncycastle.openpgp.PGPOnePassSignatureList;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
public class PgpEncryptDecryptUtil {
private static final String PROVIDER = "BC";
private static final int BUFFER_SIZE = 4096;
// 加载 BouncyCastle 提供的 JCE 供应商
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* 加密数据并输出到指定的输出流中
*
* @param data 要加密的数据
* @param publicKeyIn 加载公钥的输入流
* @param outputStream 输出加密后的数据的输出流
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static void encrypt(byte[] data, InputStream publicKeyIn, OutputStream outputStream)
throws IOException, PGPException {
// 创建公钥环
PGPPublicKeyRingCollection publicKeyRingCollection = new PGPPublicKeyRingCollection(
PGPUtil.getDecoderStream(publicKeyIn));
// 找到可用的公钥
PGPPublicKey publicKey = null;
Iterator<PGPPublicKeyRing> keyRingIterator = publicKeyRingCollection.getKeyRings();
while (publicKey == null && keyRingIterator.hasNext()) {
PGPPublicKeyRing keyRing = keyRingIterator.next();
Iterator<PGPPublicKey> keyIterator = keyRing.getPublicKeys();
while (publicKey == null && keyIterator.hasNext()) {
PGPPublicKey key = keyIterator.next();
if (key.isEncryptionKey()) {
publicKey = key;
}
}
}
if (publicKey == null) {
throw new IllegalArgumentException("Can't find public key");
}
// 创建加密数据生成器
PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(
new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256)
.setWithIntegrityPacket(true).setSecureRandom(new SecureRandom()).setProvider(PROVIDER));
encryptedDataGenerator.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(publicKey)
.setProvider(PROVIDER));
// 创建压缩输出流
ByteArrayOutputStream compressedOutputStream = new ByteArrayOutputStream();
OutputStream compressedDataOutputStream = new ArmoredOutputStream(compressedOutputStream);
PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(
CompressionAlgorithmTags.ZIP);
OutputStream compressedDataOutputStream2 = compressedDataGenerator.open(compressedDataOutputStream);
// 创建字面数据输出流
PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
OutputStream literalDataOutputStream = literalDataGenerator.open(compressedDataOutputStream2, PGPLiteralData.BINARY,
PGPLiteralData.CONSOLE, data.length, new Date());
// 写入明文数据
ByteArrayInputStream dataInputStream = new ByteArrayInputStream(data);
byte[] buffer = new byte[BUFFER_SIZE];
int length;
while ((length = dataInputStream.read(buffer, 0, buffer.length)) != -1) {
literalDataOutputStream.write(buffer, 0, length);
}
literalDataOutputStream.close();
// 关闭输出流
compressedDataGenerator.close();
compressedDataOutputStream.close();
compressedOutputStream.close();
// 加密数据并输出到指定输出流
byte[] encryptedData = compressedOutputStream.toByteArray();
OutputStream encryptedDataOutputStream = encryptedDataGenerator.open(outputStream, encryptedData.length);
encryptedDataOutputStream.write(encryptedData);
encryptedDataOutputStream.close();
}
/**
* 解密数据并返回解密后的数据
*
* @param encryptedDataIn 加载加密数据的输入流
* @param privateKeyIn 加载私钥的输入流
* @return 解密后的数据
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static byte[] decrypt(InputStream encryptedDataIn, InputStream privateKeyIn)
throws IOException, PGPException {
// 创建私钥环
PGPSecretKeyRingCollection secretKeyRingCollection = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(privateKeyIn));
// 找到可用的私钥
PGPPrivateKey privateKey = null;
Iterator<PGPSecretKeyRing> keyRingIterator = secretKeyRingCollection.getKeyRings();
while (privateKey == null && keyRingIterator.hasNext()) {
PGPSecretKeyRing keyRing = keyRingIterator.next();
Iterator<PGPSecretKey> keyIterator = keyRing.getSecretKeys();
while (privateKey == null && keyIterator.hasNext()) {
PGPSecretKey key = keyIterator.next();
if (key.isSigningKey()) {
privateKey = key.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder()
.setProvider(PROVIDER).build("".toCharArray()));
}
}
}
if (privateKey == null) {
throw new IllegalArgumentException("Can't find private key");
}
// 创建对象工厂
PGPObjectFactory objectFactory = new PGPObjectFactory(PGPUtil.getDecoderStream(encryptedDataIn));
Object object = objectFactory.nextObject();
// 找到加密数据包
PGPEncryptedData encryptedData = null;
while (encryptedData == null && object != null) {
if (object instanceof PGPEncryptedData) {
encryptedData = (PGPEncryptedData) object;
} else {
object = objectFactory.nextObject();
}
}
if (encryptedData == null) {
throw new IllegalArgumentException("Can't find encrypted data");
}
// 找到公钥并解密数据
InputStream encryptedDataInputStream = encryptedData.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder()
.setProvider(PROVIDER).build(privateKey));
PGPObjectFactory encryptedObjectFactory = new PGPObjectFactory(encryptedDataInputStream);
object = encryptedObjectFactory.nextObject();
// 找到签名列表并校验签名
PGPOnePassSignatureList signatureList = null;
while (signatureList == null && object != null) {
if (object instanceof PGPOnePassSignatureList) {
signatureList = (PGPOnePassSignatureList) object;
} else {
object = encryptedObjectFactory.nextObject();
}
}
if (signatureList != null) {
throw new PGPException("This implementation doesn't support signed data");
}
// 找到字面数据包并解压缩数据
PGPLiteralData literalData = null;
while (literalData == null && object != null) {
if (object instanceof PGPLiteralData) {
literalData = (PGPLiteralData) object;
} else {
object = encryptedObjectFactory.nextObject();
}
}
if (literalData == null) {
throw new IllegalArgumentException("Can't find literal data");
}
ByteArrayOutputStream uncompressedOutputStream = new ByteArrayOutputStream();
InputStream compressedDataInputStream = literalData.getInputStream();
PGPCompressedData compressedData = new PGPCompressedData(compressedDataInputStream);
InputStream uncompressedDataInputStream = compressedData.getDataStream();
byte[] buffer = new byte[BUFFER_SIZE];
int length;
while ((length = uncompressedDataInputStream.read(buffer, 0, buffer.length)) != -1) {
uncompressedOutputStream.write(buffer, 0, length);
}
uncompressedDataInputStream.close();
compressedDataInputStream.close();
uncompressedOutputStream.close();
return uncompressedOutputStream.toByteArray();
}
/**
* 加载公钥环
*
* @param publicKeyRingIn 加载公钥环的输入流
* @return 公钥环
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static PGPPublicKeyRingCollection loadPublicKeyRing(InputStream publicKeyRingIn)
throws IOException, PGPException {
return new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(publicKeyRingIn));
}
/**
* 加载私钥环
*
* @param secretKeyRingIn 加载私钥环的输入流
* @return 私钥环
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static PGPSecretKeyRingCollection loadSecretKeyRing(InputStream secretKeyRingIn)
throws IOException, PGPException {
return new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(secretKeyRingIn));
}
/**
* 从文件中加载公钥环
*
* @param publicKeyRingFile 加载公钥环的文件
* @return 公钥环
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static PGPPublicKeyRingCollection loadPublicKeyRingFromFile(String publicKeyRingFile)
throws IOException, PGPException {
FileInputStream fileInputStream = new FileInputStream(publicKeyRingFile);
PGPPublicKeyRingCollection publicKeyRingCollection = loadPublicKeyRing(fileInputStream);
fileInputStream.close();
return publicKeyRingCollection;
}
/**
* 从文件中加载私钥环
*
* @param secretKeyRingFile 加载私钥环的文件
* @return 私钥环
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static PGPSecretKeyRingCollection loadSecretKeyRingFromFile(String secretKeyRingFile)
throws IOException, PGPException {
FileInputStream fileInputStream = new FileInputStream(secretKeyRingFile);
PGPSecretKeyRingCollection secretKeyRingCollection = loadSecretKeyRing(fileInputStream);
fileInputStream.close();
return secretKeyRingCollection;
}
/**
* 保存公钥环到文件中
*
* @param publicKeyRing 要保存的公钥环
* @param publicKeyRingFileOut 保存公钥环的文件输出流
* @throws IOException IO异常
*/
public static void savePublicKeyRing(PGPPublicKeyRing publicKeyRing, OutputStream publicKeyRingFileOut)
throws IOException {
ArmoredOutputStream armoredOutputStream = new ArmoredOutputStream(publicKeyRingFileOut);
publicKeyRing.encode(armoredOutputStream);
armoredOutputStream.close();
}
/**
* 保存私钥环到文件中
*
* @param secretKeyRing 要保存的私钥环
* @param secretKeyRingFileOut 保存私钥环的文件输出流
* @throws IOException IO异常
*/
public static void saveSecretKeyRing(PGPSecretKeyRing secretKeyRing, OutputStream secretKeyRingFileOut)
throws IOException {
ArmoredOutputStream armoredOutputStream = new ArmoredOutputStream(secretKeyRingFileOut);
secretKeyRing.encode(armoredOutputStream);
armoredOutputStream.close();
}
/**
* 保存公钥环到文件中
*
* @param publicKeyRing 要保存的公钥环
* @param publicKeyRingFileOut 保存公钥环的文件输出流
* @throws IOException IO异常
*/
public static void savePublicKeyRingToFile(PGPPublicKeyRing publicKeyRing, String publicKeyRingFileOut)
throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(publicKeyRingFileOut);
savePublicKeyRing(publicKeyRing, fileOutputStream);
fileOutputStream.close();
}
/**
* 保存私钥环到文件中
*
* @param secretKeyRing 要保存的私钥环
* @param secretKeyRingFileOut 保存私钥环的文件输出流
* @throws IOException IO异常
*/
public static void saveSecretKeyRingToFile(PGPSecretKeyRing secretKeyRing, String secretKeyRingFileOut)
throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(secretKeyRingFileOut);
saveSecretKeyRing(secretKeyRing, fileOutputStream);
fileOutputStream.close();
}
/**
* 创建公钥环
*
* @param keyPair 密钥对
* @param userId 用户ID
* @param keyRingName 密钥环名称
* @param expirationTimeInDays 过期时间(以天为单位)
* @return 公钥环
* @throws PGPException PGP异常
*/
public static PGPPublicKeyRing createPublicKeyRing(PgpKeyPair keyPair, String userId, String keyRingName,
int expirationTimeInDays) throws PGPException {
PGPPublicKeyRingGenerator publicKeyRingGenerator = new PGPPublicKeyRingGenerator(
PGPSignature.POSITIVE_CERTIFICATION, keyPair.getPublicKey(), userId,
new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, new SecureRandom())
.setProvider(PROVIDER).build(keyPair.getPassphrase().toCharArray()),
null, null, new JcaPGPContentSignerBuilder(keyPair.getPublicKey().getAlgorithm(),
HashAlgorithmTags.SHA256), new JcePGPKeyEncryptionMethodGenerator(keyPair.getPublicKey().getAlgorithm())
.setProvider(PROVIDER), new SecureRandom(), new Date());
if (expirationTimeInDays > 0) {
publicKeyRingGenerator.addSubKey(keyPair.getPublicKey(),
new Date(System.currentTimeMillis() + expirationTimeInDays * 86400000L),
new JcaPGPContentSignerBuilder(keyPair.getPublicKey().getAlgorithm(),
HashAlgorithmTags.SHA256),
new JcePGPKeyEncryptionMethodGenerator(keyPair.getPublicKey().getAlgorithm()).setProvider(PROVIDER));
}
return publicKeyRingGenerator.generatePublicKeyRing();
}
/**
* 创建私钥环
*
* @param keyPair 密钥对
* @param userId 用户ID
* @param keyRingName 密钥环名称
* @param expirationTimeInDays 过期时间(以天为单位)
* @return 私钥环
* @throws PGPException PGP异常
*/
public static PGPSecretKeyRing createSecretKeyRing(PgpKeyPair keyPair, String userId, String keyRingName,
int expirationTimeInDays) throws PGPException {
PGPPublicKey publicKey = keyPair.getPublicKey();
PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, publicKey,
new JcaPGPContentSignerBuilder(publicKey.getAlgorithm(), HashAlgorithmTags.SHA256),
new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, new SecureRandom())
.setProvider(PROVIDER).build(keyPair.getPassphrase().toCharArray()), null, null,
new JcaPGPContentSignerBuilder(publicKey.getAlgorithm(), HashAlgorithmTags.SHA256),
new JcePGPKeyEncryptionMethodGenerator(publicKey.getAlgorithm()).setProvider(PROVIDER));
if (expirationTimeInDays > 0) {
secretKey = PGPSecretKey.addSecretSubKey(secretKey, keyPair.getPrivateKey(),
new Date(System.currentTimeMillis() + expirationTimeInDays * 86400000L),
new JcaPGPContentSignerBuilder(publicKey.getAlgorithm(), HashAlgorithmTags.SHA256),
new JcePGPKeyEncryptionMethodGenerator(publicKey.getAlgorithm()).setProvider(PROVIDER));
}
return new PGPSecretKeyRing(secretKey.getEncoded());
}
/**
* 创建密钥对
*
* @param keySize 密钥长度
* @param passphrase 密码
* @return 密钥对
* @throws PGPException PGP异常
*/
public static PgpKeyPair createKeyPair(int keySize, String passphrase) throws PGPException {
JcaPGPKeyPairGenerator keyPairGenerator = new JcaPGPKeyPairGenerator().setProvider(PROVIDER);
keyPairGenerator.generate(keySize, new SecureRandom());
PGPKeyPair keyPair = keyPairGenerator.generateKeyPair();
return new PgpKeyPair(keyPair.getPublicKey(), keyPair.getPrivateKey(), passphrase);
}
/**
* 加载密钥对
*
* @param publicKeyIn 加载公钥的输入流
* @param privateKeyIn 加载私钥的输入流
* @param passphrase 密码
* @return 密钥对
* @throws IOException IO异常
* @throws PGPException PGP异常
*/
public static PgpKeyPair loadKeyPair(InputStream publicKeyIn, InputStream privateKeyIn, String passphrase)
throws IOException,