多语言展示
当前在线:261今日阅读:113今日分享:31

Java&keytool生成RSA密钥

一个项目中先使用了AES对称加密,之后觉得密钥、摘要等还是不安全,所以又需要使用非对称加密RSA,加密密钥、摘要等信息。之前没有接触过,实际使用过程中遇到的最大疑惑就是:找了一堆资料,大家都在说明keytool怎么生成密钥、导出证书、各个参数是什么含义》...,keytool 生成的密钥库KeyStore中包含密钥(私钥/公钥)、证书。可惜,无法通过keytool工具来提取私钥...那怎么获得私钥、公钥?以Java为例:通过KeyStore类getEntry() 或者getKey()来提取私钥;通过Certificate类getPublicKey()获取公钥
工具/原料
1

keytool

2

Eclipse

Keytool生成KeyStore文件

--  生成密码仓库Hearty.storekeytool -genkey -v -alias Hearty -dname 'CN=Hearty,OU=HE,O=CUI,L=HAIDIAN,ST=BEIJING,C=CN' -keyalg RSA -keysize 2048 -keypass 5201314 -keystore Hearty.store -storepass 5201314 -validity 10000 -storetype JCEKS --  导出证书HRFax.crtkeytool -exportcert -alias Hearty -file Hearty.crt -keystore Hearty.store -storepass 5201314 -rfc -storetype JCEKSkeytool更多使用方法 及 参数说明自行查阅资料(一查一大把)

生成私钥、公钥
1

获取私钥:private static PrivateKey getPrivateKeyFromStore() throws Exception {    String alias = 'Hearty'; // KeyTool中生成KeyStore时设置的alias     String storeType = 'JCEKS'; // KeyTool中生成KeyStore时设置的storetype     char[] pw = '5201314'.toCharArray(); // KeyTool中生成KeyStore时设置的storepass     String storePath = 'E:/key/Hearty.store'; // KeyTool中已生成的KeyStore文件     storeType = null == storeType ? KeyStore.getDefaultType() : storeType;     KeyStore keyStore = KeyStore.getInstance(storeType);     InputStream is = new FileInputStream(storePath);     keyStore.load(is, pw);     // 由密钥库获取密钥的两种方式     // KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)     keyStore.getEntry(alias, new KeyStore.PasswordProtection(pw));     // return pkEntry.getPrivateKey();     return (PrivateKey) keyStore.getKey(alias, pw); }

2

保存私钥之文件:String privatePath = 'E:/key/HeartyPri.key'; // 准备导出的私钥private static void createKeyFile(Object key, String filePath) throws Exception {     FileOutputStream fos = new FileOutputStream(filePath);     ObjectOutputStream oos = new ObjectOutputStream(fos);     oos.writeObject(key);     oos.flush();     oos.close(); }

3

获取公钥:private static PublicKey getPublicKeyFromCrt() throws Exception {     String crtPath = 'E:/key/Hearty.crt'; // KeyTool中已生成的证书文件     CertificateFactory cf = CertificateFactory.getInstance('X.509');     FileInputStream in = new FileInputStream(crtPath);     Certificate crt = cf.generateCertificate(in);     return crt.getPublicKey(); }

4

保存公钥至文件:String privatePath = 'E:/key/HeartyPub.key'; // 准备导出的私钥private static void createKeyFile(Object key, String filePath) throws Exception{    FileOutputStream fos = new FileOutputStream(filePath);    ObjectOutputStream oos = new ObjectOutputStream(fos);    oos.writeObject(key);    oos.flush();    oos.close();}

测试加密、解密

1、一般公钥加密、私钥解密2、私钥加密、公钥解密也是可以的

完整源码

import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.ObjectOutputStream;import java.security.Key;import java.security.KeyStore;import java.security.PrivateKey;import java.security.PublicKey;import java.security.cert.Certificate;import java.security.cert.CertificateException;import java.security.cert.CertificateFactory;import javax.crypto.Cipher;import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.bouncycastle.util.encoders.Base64;public class KeyStoreHelper{    public static void main(String[] args) throws Exception    {        String privatePath = 'E:/key/HeartyPri.key'; // 准备导出的私钥         String publicPath = 'E:/key/HeartyPub.key'; // 准备导出的公钥         PrivateKey privateKey = getPrivateKeyFromStore();         createKeyFile(privateKey, privatePath);         PublicKey publicKey = getPublicKeyFromCrt();         createKeyFile(publicKey, publicPath);                 test(privateKey, publicKey);         test(publicKey, privateKey);         test(privateKey, privateKey);         test(publicKey, publicKey);     }     private static PrivateKey getPrivateKeyFromStore() throws Exception     {         String alias = 'Hearty'; // KeyTool中生成KeyStore时设置的alias         String storeType = 'JCEKS'; // KeyTool中生成KeyStore时设置的storetype         char[] pw = '5201314'.toCharArray(); // KeyTool中生成KeyStore时设置的storepass         String storePath = 'E:/key/Hearty.store'; // KeyTool中已生成的KeyStore文件         storeType = null == storeType ? KeyStore.getDefaultType() : storeType;         KeyStore keyStore = KeyStore.getInstance(storeType);         InputStream is = new FileInputStream(storePath); keyStore.load(is, pw);         // 由密钥库获取密钥的两种方式         // KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, new KeyStore.PasswordProtection(pw));         // return pkEntry.getPrivateKey();         return (PrivateKey) keyStore.getKey(alias, pw);     }     private static PublicKey getPublicKeyFromCrt() throws CertificateException, FileNotFoundException     {         String crtPath = 'E:/key/Hearty.crt'; // KeyTool中已生成的证书文件         CertificateFactory cf = CertificateFactory.getInstance('X.509');         FileInputStream in = new FileInputStream(crtPath);         Certificate crt = cf.generateCertificate(in);         PublicKey publicKey = crt.getPublicKey();         return publicKey;     }     private static void test(Key encryptKey, Key decryptKey) throws Exception     {         System.out.println();         String data = encryptKey.getClass().getSimpleName() + '加密' + ' ~ ' + decryptKey.getClass().getSimpleName() + '解密';         System.out.println('明文 ~ ' + data);         byte[] enb = Base64.encode(RSAencrypt(encryptKey, data.getBytes()));         String en = new String(enb);         System.out.println('加密结果 ~ ' + new String(enb));         byte[] deb = Base64.decode(en);         byte[] result = RSAdecrypt(decryptKey, deb);         System.out.println('解密结果 ~ ' + new String(result));     }     private static byte[] RSAencrypt(Key pk, byte[] data) throws Exception     {         Cipher cipher = Cipher.getInstance('RSA', new BouncyCastleProvider());         cipher.init(Cipher.ENCRYPT_MODE, pk);         int blockSize = cipher.getBlockSize();         int outputSize = cipher.getOutputSize(data.length);         int leavedSize = data.length % blockSize;         int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;         byte[] raw = new byte[outputSize * blocksSize];         int i = 0;         while (data.length - i * blockSize > 0)         {             if (data.length - i * blockSize > blockSize)             {                 cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);             }             else             {                 cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);             }             i++;         }         return raw;     }     private static byte[] RSAdecrypt(Key pk, byte[] raw) throws Exception     {         Cipher cipher = Cipher.getInstance('RSA', new BouncyCastleProvider());         cipher.init(Cipher.DECRYPT_MODE, pk);         ByteArrayOutputStream bout = null;         try         {             bout = new ByteArrayOutputStream(64);             int j = 0;            int blockSize = cipher.getBlockSize();             while (raw.length - j * blockSize > 0)             {                 bout.write(cipher.doFinal(raw, j * blockSize, blockSize));                 j++;             }             return bout.toByteArray();         }         catch (Exception e)         {             throw e;         }         finally         {            if (bout != null)            {                try                 {                     bout.close();                 }                 catch (IOException e)                 {                     e.printStackTrace();                 }             }         }     }     private static void createKeyFile(Object key, String filePath) throws Exception     {         FileOutputStream fos = new FileOutputStream(filePath);         ObjectOutputStream oos = new ObjectOutputStream(fos);         oos.writeObject(key);         oos.flush();         oos.close();     }}

注意事项

代码格式无法格式化,罪过罪过~~~

推荐信息