栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何在Java中存储和重用密钥对?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何在Java中存储和重用密钥对?

这里存在一个问题:Java几乎全部集中在TLS和实现TLS所需的加密上。对于TLS,需要私钥和证书。因此,您遇到了以下情况:

  1. 必须生成(伪造的)自签名证书以与您的公钥一起使用;或
  2. 必须找到另一种没有证书的私钥存储方式。

但是,使用(2.),您会很快得到一种不太兼容的方法。如果要这样做,可以创建一个使用PB​​E / CBC加密的PKCS#8加密私钥。

因此,这里有一些代码可以创建一个自签名证书,并使用它来存储密钥。注意到期日期,可以将其设置为100年以确保安全(或者实际上可以进行一些密钥管理)。

import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.math.BigInteger;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.KeyStore;import java.security.KeyStore.Entry;import java.security.KeyStore.PrivateKeyEntry;import java.security.KeyStoreException;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.Provider;import java.security.PublicKey;import java.security.SecureRandom;import java.security.Security;import java.security.UnrecoverableEntryException;import java.security.cert.Certificate;import java.security.cert.CertificateException;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.util.Calendar;import java.util.Date;import org.bouncycastle.asn1.x500.X500Name;import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;import org.bouncycastle.cert.X509CertificateHolder;import org.bouncycastle.cert.X509v3CertificateBuilder;import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.bouncycastle.operator.ContentSigner;import org.bouncycastle.operator.OperatorCreationException;import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;public class StoreKeyPair {    public static KeyPair generateKeyPair() throws Exception {        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");        generator.initialize(2048, new SecureRandom());        KeyPair pair = generator.generateKeyPair();        return pair;    }    public static Certificate selfSign(KeyPair keyPair, String subjectDN) throws OperatorCreationException, CertificateException, IOException    {        Provider bcProvider = new BouncyCastleProvider();        Security.addProvider(bcProvider);        long now = System.currentTimeMillis();        Date startDate = new Date(now);        X500Name dnName = new X500Name(subjectDN);        // Using the current timestamp as the certificate serial number        BigInteger certSerialNumber = new BigInteger(Long.toString(now));        Calendar calendar = Calendar.getInstance();        calendar.setTime(startDate);        // 1 Yr validity        calendar.add(Calendar.YEAR, 1);        Date endDate = calendar.getTime();        // Use appropriate signature algorithm based on your keyPair algorithm.        String signatureAlgorithm = "SHA256WithRSA";        SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(keyPair     .getPublic().getEnpred());        X509v3CertificateBuilder certificateBuilder = new X509v3CertificateBuilder(dnName,     certSerialNumber, startDate, endDate, dnName, subjectPublicKeyInfo);        ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm).setProvider(     bcProvider).build(keyPair.getPrivate());        X509CertificateHolder certificateHolder = certificateBuilder.build(contentSigner);        Certificate selfSignedCert = new JcaX509CertificateConverter()     .getCertificate(certificateHolder);        return selfSignedCert;    }    public static void main(String[] args) throws Exception {        KeyPair generatedKeyPair = generateKeyPair();        String filename = "test_gen_self_signed.pkcs12";        char[] password = "test".toCharArray();        storeToPKCS12(filename, password, generatedKeyPair);        KeyPair retrievedKeyPair = loadFromPKCS12(filename, password);        // you can validate by generating a signature and verifying it or by        // comparing the moduli by first casting to RSAPublicKey, e.g.:        RSAPublicKey pubKey = (RSAPublicKey) generatedKeyPair.getPublic();        RSAPrivateKey privKey = (RSAPrivateKey) retrievedKeyPair.getPrivate();        System.out.println(pubKey.getModulus().equals(privKey.getModulus()));    }    private static KeyPair loadFromPKCS12(String filename, char[] password) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, UnrecoverableEntryException {        KeyStore pkcs12KeyStore = KeyStore.getInstance("PKCS12");        try (FileInputStream fis = new FileInputStream(filename);) { pkcs12KeyStore.load(fis, password);        }        KeyStore.ProtectionParameter param = new KeyStore.PasswordProtection(password);        Entry entry = pkcs12KeyStore.getEntry("owlstead", param);        if (!(entry instanceof PrivateKeyEntry)) { throw new KeyStoreException("That's not a private key!");        }        PrivateKeyEntry privKeyEntry = (PrivateKeyEntry) entry;        PublicKey publicKey = privKeyEntry.getCertificate().getPublicKey();        PrivateKey privateKey = privKeyEntry.getPrivateKey();        return new KeyPair(publicKey, privateKey);    }    private static void storeToPKCS12( String filename, char[] password, KeyPair generatedKeyPair) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, OperatorCreationException {        Certificate selfSignedCertificate = selfSign(generatedKeyPair, "CN=owlstead");        KeyStore pkcs12KeyStore = KeyStore.getInstance("PKCS12");        pkcs12KeyStore.load(null, null);        KeyStore.Entry entry = new PrivateKeyEntry(generatedKeyPair.getPrivate(),     new Certificate[] { selfSignedCertificate });        KeyStore.ProtectionParameter param = new KeyStore.PasswordProtection(password);        pkcs12KeyStore.setEntry("owlstead", entry, param);        try (FileOutputStream fos = new FileOutputStream(filename)) { pkcs12KeyStore.store(fos, password);        }    }}

请注意,我懒得不能正确处理异常。

这段代码使用的答案略有改动,请参阅我的评论以了解更改代码的原因。


当然,公钥也可以单独存储。只需调用

getEnpred
并存储生成的SubjectPublicKeyInfo结构即可。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/498308.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号