Java密码学
来源:互联网 发布:gta5捏脸数据女韩国 编辑:程序博客网 时间:2024/06/05 04:15
自证书
自证书 , 就是自己办法给自己 (我是国王, 我说我没错就没错!!)
sun.security.x509的自签名
CertAndKeyGen gen = new CertAndKeyGen("RSA", "SHA1WithRSA");gen.generate(1024);//generate private key for sign certX509Certificate cert = gen.getSelfCertificate(new X500Name("CN=caliburn"), (long) 50 * 365 * 24 * 3600);
- 这里CertAndKeyGen包含了KeyPairGenerator类, 也就是, 之类有生成公钥和私钥的算法
- 第三行参数 : 公共名称 (CN) , 有效时间
https://www.ibm.com/support/knowledgecenter/zh/SSZPE3_9.1.2/Platform/SSL_1/SSL_1_About_SSL_certs.html
CN值, 用于匹配, 客户端登陆的是不是CA发的证书的网站
非自证书 (签名证书)
也就是要去CA那里申请, 需要发个request, 如何构造request
client端
GenerateKeys gk = new GenerateKeys(1024);//构造公钥和私钥PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder( new X500Principal("CN=Requested Test Certificate"), gk.getPublicKey());//CN和公钥JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256withRSA");//签名算法ContentSigner signer = csBuilder.build(gk.getPrivateKey());//私钥签名PKCS10CertificationRequest csr = p10Builder.build(signer);
这里生成的私钥要自己保存好, 放到keystore也好, 生成一个文件也好
CA端 (sever端):
PKCS10CertificationRequest csr = ...;//获取申请/*获取CA端的自证书, 用于构造信息, 这里需要注意, 我们要构造的是BC的X.509证书, 因为这个代码环境都是BC, 用java.security的证书类是不能操作的*/CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); X509Certificate cacert = (X509Certificate) certFactory.generateCertificate( FileUtils.openInputStream(new File("project/4d/sever/rootcer.pem")));//一大堆参数 ,填充到生成器里AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); org.bouncycastle.asn1.x500.X500Name issuer = new org.bouncycastle.asn1.x500.X500Name(cacert.getSubjectX500Principal().getName()); BigInteger serial = new BigInteger(32, new SecureRandom()); Date from = new Date(); Date to = new Date(System.currentTimeMillis() + (365 * 80 * 86400000L)); DigestCalculator digCalc = new BcDigestCalculatorProvider().get(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1)); X509v3CertificateBuilder certgen = new X509v3CertificateBuilder(issuer, serial, from, to, csr.getSubject(), csr.getSubjectPublicKeyInfo()); //CA端进行签名, 才有具有法律效力 ContentSigner signer = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(PrivateKeyFactory.createKey(CA的私钥.getEncoded())); //生成BC结构的证书 Security.addProvider(new BouncyCastleProvider()); X509Certificate bc = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certgen.build(signer)); //最终生成的是java.security的证书
我国使用的是双证书, 也就是我们还要弄一个加密证书.
过程
- 生成公钥A和私钥A
- 从request|刚刚生成签名证书里取相关信息( 公钥B和其他信息 )
- 生成对称加密C , 加密私钥A
- 公钥B加密该对称加密C
- 放进一个自定义的协议ASN1Object
这里主要讲讲, 如何从request里获取公钥
先看request的ASN结构
RFC 2986 - PKCS #10: Certification Request Syntax
CertificationRequestInfo ::= SEQUENCE { version INTEGER { v1(0) } (v1,...), subject Name, subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, attributes [0] Attributes{{ CRIAttributes }} } SubjectPublicKeyInfo { ALGORITHM : IOSet} ::= SEQUENCE { algorithm AlgorithmIdentifier {{IOSet}}, subjectPublicKey BIT STRING }
X.509格式则为 (X.509为证书公钥的结构)
SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING }
于是乎, 我们就明白编码结构为X.509 (除此以为, 还有PKCS#1结构, 该结构对应的是AlgorithmIdentifier, 可以通过该结构, 将X.509转换成PKCS#1)
所以,我们先获取该结构的字节码, 在转换成X509, 最后通过工厂类进行操作即可
PKCS10CertificationRequest csr=...;X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(csr.getSubjectPublicKeyInfo().toASN1Primitive().getEncoded());PublicKey Signedpk =KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec);
笔者之前也说过, JCA(这里是BC)和JCE(Java自身的)之前的转换, 是通过Jca开头的类来转换
PKCS10CertificationRequest csr=...;JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest = new JcaPKCS10CertificationRequest(csr);PublicKey Signedpk = jcaPKCS10CertificationRequest.getPublicKey();
番外
也可以通过转换成PKCS#1的结构, 再进行提取(不建议, 与其他代码不融洽)
PKCS10CertificationRequest csr=...RSAKeyParameters rsa = (RSAKeyParameters) PublicKeyFactory.createKey(csr.getSubjectPublicKeyInfo());RSAPublicKeySpec rsaSpec = new RSAPublicKeySpec(rsa.getModulus(), rsa.getExponent());PublicKey Signedpk = KeyFactory.getInstance("RSA").generatePublic(rsaSpec);
阅读全文
1 0
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- 收藏.Java.密码学
- [HAOI2007]理想的正方形
- maven环境配置
- 我是名程序猿?工作了一年半--参与过大型项目的开发--但至今我写的代码总量没超过1000行。
- 接口java.util.Map.Entry的使用
- HC-SR04超声波模块传感器
- Java密码学
- Codeforces839A Arya and Bran
- HDU6118(费用流水题)
- [转载] Android JNI编程—JNI基础
- Linux设备驱动之plat_led驱动测试
- uva1606
- stm32学习笔记(四)外部中断
- SSL P1861 提高组 无限序列
- 高质量C/C++编程