java基于BouncyCastle实现RSA算法的加密、解密

Bouncy Castle Crypto是一个Java实现的加密包,同时也有C#版本。它包含一套轻量级的API可以在包括J2ME在内的绝大多数环境中运行。部分手机不支持JSR177也可使用该加密包实现加密功能。Bouncy Castle加密包包含了大多数流行的加密实现(如:AES、DES、Blowfish等)、散列算法(如:MD5、SHA等)、字节字符编码(如:Base64)等。

       Bouncy Castle API通过加密引擎(位于org.bouncycastle.crypto.引擎中)来提供密码实现,这些引擎实现了特定的接口,比如 AsymmetricBlockCipher、BlockCipher或StreamCipher(所有这些接口都可以在 org.bouncycastle.crypto包中找到)。这些接口都具有一个共同的用途:它们让你初始化密码,以字节数组的形式提供要被加密或解密的 数据(既可以以块的形式也可以作为消息流的一部分提供),然后执行加密或解密操作。与使用JCA和SATSA-CRYPTO API一样,当初始化一个密码实现时,你指定想要该实现执行加密还是解密,以及操作中要使用的密钥细节。

        除了支持许多不同密码算法,Bouncy Castle API还为其支持的密码提供了密钥生成算法。这是该API的一个重要特性,因为在编写应用程序时,安全的密钥生成和分发至关重要。 

       注意 :尽管安全密钥生成是Bouncy Castle API提供的一个重要功能,但仅适用该功能还远远不够。应用程序使用其密钥的方式与创建密钥的方式同样重要;弱存储或交换(比如通过不安全的网络通道共享对称密码算法的密钥)抵消了出色的密钥生成算法的强大作用。

前提:

       你需要使用到bcprov-ext-jdk15on-161.jar的 jar 包。

可参考:https://blog.csdn.net/hqy1719239337/article/details/88690163

maven:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.60</version>
</dependency>

实现如下:

package testRsa;
 
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.crypto.generators.*;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.crypto.*;
import org.bouncycastle.crypto.util.PrivateKeyFactory;
import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
import org.bouncycastle.crypto.util.PublicKeyFactory;
import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
import org.bouncycastle.crypto.engines.*;
import org.bouncycastle.asn1.pkcs.*;
import org.bouncycastle.asn1.*;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.*;
 
public class test_rsa {
public static void main(String[] args) throws Exception {
     //生成密钥对
     RSAKeyPairGenerator rsaKeyPairGenerator = new RSAKeyPairGenerator();
     RSAKeyGenerationParameters rsaKeyGenerationParameters = new RSAKeyGenerationParameters(BigInteger.valueOf(3),
    		                                                     new SecureRandom(), 1024, 25);
     //初始化参数  
     rsaKeyPairGenerator.init(rsaKeyGenerationParameters); 
     AsymmetricCipherKeyPair keyPair = rsaKeyPairGenerator.generateKeyPair();
     //公钥    
     AsymmetricKeyParameter publicKey = keyPair.getPublic();
     //私钥
     AsymmetricKeyParameter privateKey = keyPair.getPrivate();
     
     SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(publicKey);
     PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(privateKey);
     //变字符串
     ASN1Object asn1ObjectPublic = subjectPublicKeyInfo.toASN1Primitive();
     byte[] publicInfoByte = asn1ObjectPublic.getEncoded();
     ASN1Object asn1ObjectPrivate = privateKeyInfo.toASN1Primitive();
     byte[] privateInfoByte = asn1ObjectPrivate.getEncoded();
     //这里可以将密钥对保存到本地
     final Base64.Encoder encoder64 = Base64.getEncoder();
     System.out.println("PublicKey:\n" +  encoder64.encodeToString(publicInfoByte));
     System.out.println("PrivateKey:\n" + encoder64.encodeToString(privateInfoByte));
     //加密、解密
     ASN1Object pubKeyObj = subjectPublicKeyInfo.toASN1Primitive();//这里也可以从流中读取,从本地导入
     AsymmetricKeyParameter pubKey = PublicKeyFactory.createKey(SubjectPublicKeyInfo.getInstance(pubKeyObj));
     AsymmetricBlockCipher cipher = new RSAEngine();
     cipher.init(true, pubKey);//true表示加密
 
     final Base64.Decoder decoder64 = Base64.getDecoder();
     //加密
     String data = "成aa功324$$了#*(=-nh)。。。";
     System.out.println("\n明文:" + data);
     byte[] encryptData = cipher.processBlock(data.getBytes("utf-8")
                                              , 0, data.getBytes("utf-8").length);
     System.out.println("密文:" + encoder64.encodeToString(encryptData));
 
     //解密
     AsymmetricKeyParameter priKey = PrivateKeyFactory.createKey(privateInfoByte);
     cipher.init(false, priKey);//false表示解密
     byte[] decriyptData=cipher.processBlock(encryptData, 0, encryptData.length);
     String decryptData = new String(decriyptData,"utf-8");
     System.out.println("解密后数据:" + decryptData);
    }
}

结果:

 

 参考:https://blog.csdn.net/a571574085/article/details/81335095

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BouncyCastleJava 平台上的一个加解密库,支持多种加密算法,包括 PGP 加解密。以下是使用 BouncyCastle 实现 PGP 加密解密文件的示例代码: 1. 加载 BouncyCastle Provider: ``` Security.addProvider(new BouncyCastleProvider()); ``` 2. 生成 PGP 密钥对: ``` PGPKeyPairGenerator kpg = new JcaPGPKeyPairGenerator().setProvider("BC").setAlgorithm(AsymmetricAlgorithmTags.RSA_GENERAL).setKeySize(2048); PGPKeyPair kp = kpg.generate(); ``` 3. 导出公钥和私钥: ``` PGPPublicKeyRing publicKeyRing = new PGPPublicKeyRing(kp.getPublicKey().getEncoded(), new JcaKeyFingerprintCalculator()); PGPPublicKey publicKey = publicKeyRing.getPublicKey(); PGPPrivateKey privateKey = kp.getPrivateKey(); ``` 4. 加密文件: ``` // 创建加密器 PGPEncryptorBuilder builder = new JcePGPEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).setSecureRandom(new SecureRandom()); builder.setProvider("BC"); PGPEncryptor encryptor = builder.build(publicKey); // 创建输出流 File outputFile = new File("encrypted.pgp"); OutputStream outputStream = new FileOutputStream(outputFile); // 创建压缩器 PGPCompressedDataGenerator compressor = new PGPCompressedDataGenerator(CompressionAlgorithmTags.ZIP); OutputStream compressedOutputStream = compressor.open(outputStream); // 创建签名器 PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA256).setProvider("BC")); signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey); signatureGenerator.generateOnePassVersion(false).encode(compressedOutputStream); // 创建字节流加密器 PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator(); OutputStream literalOutputStream = literalDataGenerator.open(compressedOutputStream, PGPLiteralData.BINARY, "filename", new Date(), new byte[1024]); // 加密文件内容 File inputFile = new File("input.txt"); InputStream inputStream = new FileInputStream(inputFile); byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) != -1) { literalOutputStream.write(buffer, 0, length); } inputStream.close(); // 关闭流 literalDataGenerator.close(); signatureGenerator.generate().encode(compressedOutputStream); compressor.close(); encryptor.close(); outputStream.close(); ``` 5. 解密文件: ``` // 创建解密器 PGPObjectFactory factory = new JcaPGPObjectFactory(new FileInputStream("encrypted.pgp")); PGPEncryptedDataList encryptedDataList = (PGPEncryptedDataList) factory.nextObject(); PGPPBEEncryptedData pbeEncryptedData = (PGPPBEEncryptedData) encryptedDataList.get(0); PGPPrivateKey privateKey = findPrivateKey("userid", "password".toCharArray()); InputStream decryptedInputStream = pbeEncryptedData.getDataStream(new JcePBEDataDecryptorFactoryBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(privateKey)); // 创建签名校验器 PGPObjectFactory plainFactory = new JcaPGPObjectFactory(decryptedInputStream); PGPOnePassSignatureList signatureList = (PGPOnePassSignatureList) plainFactory.nextObject(); PGPOnePassSignature signature = signatureList.get(0); PGPPublicKey publicKey = findPublicKey(signature.getKeyID()); signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey); PGPLiteralData literalData = (PGPLiteralData) plainFactory.nextObject(); InputStream literalInputStream = literalData.getInputStream(); // 校验签名 byte[] buffer = new byte[1024]; int length; while ((length = literalInputStream.read(buffer)) != -1) { signature.update(buffer, 0, length); } if (signature.verify(((PGPSignatureList) plainFactory.nextObject()).get(0))) { System.out.println("Signature verified"); } else { System.out.println("Signature not verified"); } // 读取文件内容 while ((length = literalInputStream.read(buffer)) != -1) { // 处理文件内容 } literalInputStream.close(); decryptedInputStream.close(); ``` 其中,`findPrivateKey` 和 `findPublicKey` 方法根据指定的用户 ID 查找对应的私钥和公钥。在实际使用时,需要将用户 ID 和密钥信息存储在合适的位置,例如文件或数据库中,然后在程序中进行读取。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值