加密(一):BouncyCastle(转)

原文链接+自己学习整理编写

 

1、为什么要使用BouncyCastle?

我们平常都使用jdk自带的加密包对数据进行加密,加密方式也都是使用的默认的,如果我们想选择别的加密方式,发现会报错,比如如下代码:

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");  
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".getBytes("UTF-8"), "AES"));  
cipher.doFinal("QWEASDZS".getBytes("UTF-8")); 

这时候我们就需要借助BouncyCastle了。

 

2、如何使用BouncyCastle?

2.1、方式一

(1)去BouncyCastle官网下载provider的包,然后放入$JAVA_HOME\jre\lib\ext目录下;

(2)修改配置文件$JAVA_HOME\jre\lib\security\java.security,加入一行配置:security.provider.按顺序填数字=org.bouncycastle.jce.provider.BouncyCastleProvider

(3)代码如下:

  1. Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");  
  2. cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".getBytes("UTF-8"), "AES"));  
  3. cipher.doFinal("QWEASDZS".getBytes("UTF-8"));  

2.2、方式二【个人推荐】:在代码中通过maven引入BouncyCastle的包

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

我用的是jdk1.8,使用正常。

 

3、注意点

 

出于某些原因,可能需要去官网下载JCE包,替换掉$JAVA_HOME\jre\lib\security目录下的内容,其次密钥的长度也要注意。

4、写个小程序测试一下

import java.security.*;
public class Check {
public static void main(String[] args) {
System.out.println("-------列出加密服务提供者-----");
Provider[] pro=Security.getProviders();
for(Provider p:pro){
System.out.println("Provider:"+p.getName()+" - version:"+p.getVersion());
System.out.println(p.getInfo());
}
System.out.println("");
System.out.println("-------列出系统支持的消息摘要算法:");
for(String s:Security.getAlgorithms("MessageDigest")){
System.out.println(s);
}
System.out.println("-------列出系统支持的生成公钥和私钥对的算法:");
for(String s:Security.getAlgorithms("KeyPairGenerator")){
System.out.println(s);
}
}
}

可以看到列出系统已经安装的所有的JCE提供者,并且著名的一些的消息摘要算法:MD5,生成公钥和私钥对的算法RSA等都在其中。

5、最后,我们来试一下公钥、密钥的转换

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
...
...
...
//1、先是我们私钥Private key
PrivateKey priv = pair.getPrivate();
byte[] privBytes = priv.getEncoded();
PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(privBytes);
ASN1Encodable encodable = pkInfo.parsePrivateKey();
ASN1Primitive primitive = encodable.toASN1Primitive();
byte[] privateKeyPKCS1 = primitive.getEncoded();
...
...
...
//将私钥从PKCS8转换为PKCS1:
PrivateKey priv = pair.getPrivate();
byte[] privBytes = priv.getEncoded();
PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(privBytes);
ASN1Encodable encodable = pkInfo.parsePrivateKey();
ASN1Primitive primitive = encodable.toASN1Primitive();
byte[] privateKeyPKCS1 = primitive.getEncoded();
...
...
...
//将私钥从PKCS1转换为PEM:
PemObject pemObject = new PemObject("RSA PRIVATE KEY", privateKeyPKCS1);
StringWriter stringWriter = new StringWriter();
PemWriter pemWriter = new PemWriter(stringWriter);
pemWriter.writeObject(pemObject);
pemWriter.close();
String pemString = stringWriter.toString();

//接下来测试一下:使用命令行OpenSSL检查密钥格式是否符合预期
openssl rsa -in rsa_private_key.pem -noout -text

//2、然后是我们公钥Public key
//转换为PKCS1:
PublicKey pub = pair.getPublic();
byte[] pubBytes = pub.getEncoded();
SubjectPublicKeyInfo spkInfo = SubjectPublicKeyInfo.getInstance(pubBytes);
ASN1Primitive primitive = spkInfo.parsePublicKey();
byte[] publicKeyPKCS1 = primitive.getEncoded();

//将PKCS1转换为PEM
PemObject pemObject = new PemObject("RSA PUBLIC KEY", publicKeyPKCS1);
StringWriter stringWriter = new StringWriter();
PemWriter pemWriter = new PemWriter(stringWriter);
pemWriter.writeObject(pemObject);
pemWriter.close();
String pemString = stringWriter.toString();

//接下来测试一下:使用命令行OpenSSL检查是否符合预期
openssl rsa -in rsa_public_key.pem -RSAPublicKey_in -noout -text



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值