久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

如何在 Java 中存儲和重用密鑰對?

How to store and reuse keypair in Java?(如何在 Java 中存儲和重用密鑰對?)
本文介紹了如何在 Java 中存儲和重用密鑰對?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我想生成一個密鑰對并重復使用它.

I am wanting generate a keypair once and reuse it.

public static KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048, new SecureRandom());
        KeyPair pair = generator.generateKeyPair();

        return pair;
}

我該怎么做?

推薦答案

這里有一點問題:Java 的重點幾乎完全是 TLS 和實現 TLS 所需的密碼學.對于 TLS,需要私鑰和證書.因此,您會遇到以下情況:

There is a bit of a problem here: Java's focus is almost entirely on TLS and the cryptography required to implement TLS. For TLS a private key and a certificate is required. So you get into a situation where you:

  1. 必須生成(偽造的)自簽名證書才能與您的公鑰一起使用,或者;
  2. 必須找到另一種在沒有證書的情況下存儲私鑰的方法.

但是,使用 (2.) 您很快就會得到一個不太兼容的方法.如果你想這樣做,你可以創建一個使用 PBE/CBC 加密的 PKCS#8 加密私鑰.

However, with (2.) you quickly get a method that isn't very compatible. If you want to go that way, you could create a PKCS#8 encrypted private key that is encrypted using PBE / CBC.

所以這里有一些代碼來創建一個自簽名證書并使用它來存儲密鑰.請注意到期日期,您可以將其設置為 100 年以確保安全(或者您實際上可以進行一些密鑰管理).

So here's some code to create a self signed certificate and use that to store the key. Note the expiration date, you could set it to 100 years to be on the safe side (or you could actually do some key management).

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().getEncoded());

        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);
        }
    }
}

請注意,我懶得正確處理異常.

Note that I was too lazy to properly handle the exceptions.

此代碼使用此答案的略微更改版本,請參閱我的評論了解我更改代碼的原因.

This code uses a slightly altered version of this answer, see my comments for why I changed the code.

當然,公鑰也可以單獨存儲.只需調用 getEncoded 并存儲生成的 SubjectPublicKeyInfo 結構.

The public key can of course be stored separately as well. Just call getEncoded and store the resulting SubjectPublicKeyInfo structure.

這篇關于如何在 Java 中存儲和重用密鑰對?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Java Remove Duplicates from an Array?(Java從數組中刪除重復項?)
How to fix Invocation failed Unexpected Response from Server: Unauthorized in Android studio(如何修復調用失敗來自服務器的意外響應:在 Android 工作室中未經授權)
AES encryption, got extra trash characters in decrypted file(AES 加密,解密文件中有多余的垃圾字符)
AES Error: Given final block not properly padded(AES 錯誤:給定的最終塊未正確填充)
Detecting incorrect key using AES/GCM in JAVA(在 JAVA 中使用 AES/GCM 檢測不正確的密鑰)
AES-256-CBC in Java(Java 中的 AES-256-CBC)
主站蜘蛛池模板: 三级黄色大片网站 | 日本精品视频 | 一级黄色日本片 | 操网站 | 欧美一区免费在线观看 | 综合久久亚洲 | 久草热在线 | 亚洲成人av| 久久亚洲国产 | 精品久久久久久久久亚洲 | 日韩久久久久久 | 成人在线精品 | 精品国产一区二区三区久久久久久 | 日韩欧美在 | 中文字幕亚洲欧美 | 国产日产精品一区二区三区四区 | 亚洲精彩视频 | 久久精品亚洲国产 | 亚洲区中文字幕 | 少妇性l交大片免费一 | 午夜不卡一区二区 | 一级高清视频 | 色视频在线观看 | 婷婷综合激情 | 四虎最新地址 | 国产中文字幕在线观看 | 91精品国产乱码久久久久久久 | 久久中文免费视频 | 一区二区不卡 | 国产精品伦理一区二区三区 | 国产一区二区 | 久久一| 久久国产精品精品 | 99精品视频免费在线观看 | 精品国产亚洲一区二区三区大结局 | 一级片免费在线观看 | 色爱综合| 一区二区三区视频在线观看 | 国产精品久久久一区二区三区 | 99国产精品久久久久老师 | 国内自拍视频在线观看 |