Java 使用PGP实现签名加密

具体的给一个我写的Util类,在这里使用到了第三方包cryptix,具体的可以去www.cryptix.org网站上去找资料。ceryptix的jar包放在附件中。
示例类:

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


import cryptix.message.EncryptedMessage;
import cryptix.message.EncryptedMessageBuilder;
import cryptix.message.KeyBundleMessage;
import cryptix.message.LiteralMessage;
import cryptix.message.LiteralMessageBuilder;
import cryptix.message.Message;
import cryptix.message.MessageException;
import cryptix.message.MessageFactory;
import cryptix.message.NotEncryptedToParameterException;
import cryptix.message.SignedMessage;
import cryptix.message.SignedMessageBuilder;
import cryptix.openpgp.PGPArmouredMessage;
import cryptix.pki.KeyBundle;

public class PGPUtil {

/**
* 添加提供者
*/
static{
Security.addProvider(new cryptix.jce.provider.CryptixCrypto());
Security.addProvider(new cryptix.openpgp.provider.CryptixOpenPGP() );
}

/**
* 构建 LiteralMessage 对象
* @param message
* @return
* @throws MessageException
*/
private static LiteralMessage buildLiteralMessage(byte[] message) throws MessageException{
LiteralMessageBuilder lmb = null;

try {
lmb = LiteralMessageBuilder.getInstance("OpenPGP");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
lmb.init(message);
LiteralMessage literal = (LiteralMessage)lmb.build();
return literal;
}

/**
* 使用多个公钥对明文加密
* @param plain 明文
* @param recipientKeys 公钥集合
* @return 加密后的明文
* @throws MessageException
*/
public static byte[] encrypt(byte[] plain,List<KeyBundle> recipientKeys) throws MessageException{
LiteralMessage literal = buildLiteralMessage(plain);

EncryptedMessageBuilder emb = null;
try {
emb = EncryptedMessageBuilder.getInstance("OpenPGP");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
emb.init(literal);

//添加接受者
for(KeyBundle key : recipientKeys){
emb.addRecipient(key);
}
//压缩
emb.setAttribute("compressed", "true");
//得到加密信息
Message msg = emb.build();
PGPArmouredMessage pgpMsg = new PGPArmouredMessage(msg);
return pgpMsg.getEncoded();
}

/**
* 使用单张公钥加密
* @param plain 明文
* @param publicKey 公钥
* @return 返回加密后的密文
* @throws MessageException
*/
public static byte[] encrypt(byte[] plain,KeyBundle publicKey) throws MessageException{
List<KeyBundle> list = new ArrayList<KeyBundle>();
list.add(publicKey);
return encrypt(plain, list);

}

/**
* 使用私钥和密码对明文签名
* @param plain 明文
* @param privateKey 私钥
* @param keypass 私钥密码
* @return 签名后的明文
* @throws MessageException
* @throws UnrecoverableKeyException
*/
public static byte[] sign(byte[] plain,KeyBundle privateKey,String keypass)throws MessageException,UnrecoverableKeyException{
SignedMessageBuilder smb = null;
try {
smb = SignedMessageBuilder.getInstance("OpenPGP");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

// SignedMessageBuilder smb = SignedMessageBuilder.getInstance("OpenPGP/V3");

LiteralMessage literal = buildLiteralMessage(plain);
smb.init(literal);
smb.addSigner(privateKey, keypass.toCharArray());

Message msg = smb.build();
PGPArmouredMessage armoured = new PGPArmouredMessage(msg);
return armoured.getEncoded();
}

/**
* 使用私钥和密码解密加密后的数据
* @param encrypted PGP加密过的数据
* @param privateKey 私钥
* @param keypass 私钥密码
* @return 解密后的明文
* @throws MessageException
* @throws IOException
* @throws UnrecoverableKeyException
* @throws NotEncryptedToParameterException
*/
public static byte[] decrypt(byte[] encrypted,KeyBundle privateKey,String keypass) throws MessageException, IOException, UnrecoverableKeyException, NotEncryptedToParameterException{

MessageFactory mf = null;
try {
mf = MessageFactory.getInstance("OpenPGP");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

Collection msgs = mf.generateMessages(new ByteArrayInputStream(encrypted));

//得到集合中的EncryptedMessage对象
Message message = (Message)msgs.iterator().next();

if (!(message instanceof EncryptedMessage)) {
throw new MessageException("Not a encrypted message.");
}

EncryptedMessage em = (EncryptedMessage)message;
Message msg = em.decrypt(privateKey,keypass.toCharArray());
return ((LiteralMessage)msg).getBinaryData();
}

/**
* 解密验签
* @param encrypted 密文
* @param privateKey 私钥
* @param keypass 私钥密码
* @param publicKey 公钥
* @return 返回明文
* @throws UnrecoverableKeyException
* @throws MessageException
* @throws IOException
* @throws NotEncryptedToParameterException
*/
public static byte[] decryptVerify(byte[] encrypted,KeyBundle privateKey,String keypass,KeyBundle publicKey) throws UnrecoverableKeyException, MessageException, IOException, NotEncryptedToParameterException{
return PGPUtil.verify(PGPUtil.decrypt(encrypted, privateKey, keypass), publicKey);
}

/**
* 验证Message
* @param signed 验证的内容
* @param publickey 公钥
* @return 返回验证后的内容
* @throws MessageException
* @throws IOException
*/
public static byte[] verify(byte[] signed,KeyBundle publickey) throws MessageException, IOException{

MessageFactory mf = null;
try {
mf = MessageFactory.getInstance("OpenPGP");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

Message msg = (Message)mf.generateMessages(new ByteArrayInputStream(signed)).iterator().next();
if (!(msg instanceof SignedMessage)) {
throw new MessageException(" Not a signed message.");
}

SignedMessage sm = (SignedMessage)msg;
if (sm.verify(publickey)) {

} else {
throw new MessageException(" Signature verify fail. ");
}

if (!(sm.getContents() instanceof LiteralMessage)){
throw new MessageException(" Not a signed message.");
}

LiteralMessage lm = (LiteralMessage)sm.getContents();
return lm.getBinaryData();
}

/**
* 流转换为PGP KeuBundle 对象
* @param inputStream Key
* @return 转换后的 KeuBundle
* @throws MessageException
* @throws IOException
*/
public static KeyBundle streamToKeyBundle(InputStream inputStream) throws MessageException, IOException {
MessageFactory messageFactory = null;
try {
messageFactory = MessageFactory.getInstance("OpenPGP");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
Collection msgs = messageFactory.generateMessages(inputStream);
KeyBundleMessage keybm = (KeyBundleMessage)msgs.iterator().next();

return keybm.getKeyBundle();

}

/**
* 签名加密
* @param plain 明文
* @param privateKey 私钥
* @param keypass 私钥密码
* @param recipientKeys 公钥
* @return 返回签名加密后的数据
* @throws UnrecoverableKeyException
* @throws MessageException
*/
public static byte [] signAndEncrypt(byte[] plain,KeyBundle privateKey,String keypass,List<KeyBundle> recipientKeys) throws UnrecoverableKeyException, MessageException{
return PGPUtil.encrypt(PGPUtil.sign(plain, privateKey, keypass),recipientKeys);
}

/**
* 签名加密
* @param plain 明文
* @param privateKey 私钥
* @param keypass 私钥密码
* @param recipientKeys 公钥
* @return 返回签名加密后的数据
* @throws UnrecoverableKeyException
* @throws MessageException
*/
public static byte [] signAndEncrypt(byte[] plain,KeyBundle privateKey,String keypass,KeyBundle publicKey) throws UnrecoverableKeyException, MessageException{
return PGPUtil.encrypt(PGPUtil.sign(plain, privateKey, keypass),publicKey);
}
}


需要修改jre里面的security下面的local_policy.jar包给替换。
替换为附件中的local_policy.jar包,然后找到security文件下面的java.security文件,在文件中添加下面的内容:
security.provider.10=cryptix.jce.provider.CryptixCrypto
security.provider.11=cryptix.openpgp.provider.CryptixOpenPGP
增加java的cryptix提供者,sun提供的jre的security下面的local_policy.jar不提供cryptix的加密算法。
在附件中的testCert.jar是用来测试的公钥和私钥。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PGP(Pretty Good Privacy)是一种加密签名数据的标准协议,Java可以通过Bouncy Castle库实现PGP加密解密,具体步骤如下: 1. 首先需要导入Bouncy Castle库,可以在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpg-jdk15on</artifactId> <version>1.68</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.68</version> </dependency> ``` 2. 生成PGP密钥对(公钥和私钥)。 3. 使用公钥加密明文数据。 ``` PGPPublicKey publicKey = ... // 获取公钥 byte[] plainText = ... // 明文数据 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(true).setSecureRandom(new SecureRandom()).setProvider("BC")); encryptedDataGenerator.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(publicKey).setProvider("BC")); OutputStream encryptedOutputStream = encryptedDataGenerator.open(outputStream, new byte[1024]); encryptedOutputStream.write(plainText); encryptedOutputStream.close(); byte[] encryptedData = outputStream.toByteArray(); ``` 4. 使用私钥解密加密后的数据。 ``` PGPSecretKey secretKey = ... // 获取私钥 char[] passPhrase = ... // 私钥的口令 InputStream inputStream = new ByteArrayInputStream(encryptedData); PGPObjectFactory objectFactory = new JcaPGPObjectFactory(inputStream); PGPEncryptedDataList encryptedDataList = (PGPEncryptedDataList) objectFactory.nextObject(); Iterator<PGPPublicKeyEncryptedData> it = encryptedDataList.getEncryptedDataObjects(); PGPPublicKeyEncryptedData encryptedData = it.next(); InputStream decryptedInputStream = encryptedData.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(secretKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(passPhrase)))); byte[] decryptedData = IOUtils.toByteArray(decryptedInputStream); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值