KeyStorte存储Rsa非对称加密秘钥

本文详细介绍了RSA非对称加密的工作原理,重点讲解了Java中的Keystore概念,包括其在存储SSL证书、数字证书、密钥对和信任项的应用,以及如何使用命令行和代码生成和管理Keystore,展示了如何使用公钥和私钥进行加密解密操作。
摘要由CSDN通过智能技术生成

一、 RSA:非对称加密是一种加密方式,加密和解密使用不同的密钥。发送方使用公钥进行加密,接收方使用私钥进行解密。因为公钥可以公开,所以只有私钥知道的加密信息能够被解密,这种方式的优点是安全性高,缺点是相对于对称加密而言,加密速度较慢。

        

        Keystore:在Java中,keystore是用于存储密钥、证书和信任项的安全存储库。它通常用于管理SSL证书、数字证书和私钥,以便在加密通信、数字签名和认证等安全领域使用。

具体来说,keystore可以用于以下几个方面:

  1. 存储SSL证书和私钥,用于安全通信。在使用HTTPS协议进行加密通信时,服务器和客户端都需要从keystore中加载SSL证书和私钥。
  2. 存储数字证书,用于数字签名和认证。数字证书可以用于验证通信双方的身份,防止中间人攻击。
  3. 存储信任项,用于信任其他实体的证书。在建立SSL连接时,客户端需要信任服务器的证书,服务器需要信任客户端的证书,这些信任项可以从keystore中加载。

二、实际应用


KeyStore是一个存储库,可用于存储一系列密钥(Secret Key)、密钥对(Key Pair)或证书(Certificate)

密钥:只有一个钥,一般是对称加密时使用。
密钥对:包含公钥(Public Key)和私钥(Private Key),一般是非对称加密时使

KeyStore可以设置密码。
密钥、密钥对、证书在KeyStore统称为Key(又称"条目"),每一个Key通过alias(别名)区分。Key也可以设置密码。
KeyStore可以理解为一种规范,常见的 JKS(Java Key Store)只是KeyStore的一种实现类型,其他的还有PKCS12、JCEKS等。
JKS 可以存储密钥对和证书,但不能用于存储密钥。
PKCS12、JCEKS 都可以存储密钥对、证书、密钥。

命令方式生成Keystore:

#命令方法生成keystore JDK bin cmd
.\keytool.exe -genkeypair
  -alias dataKeystore  //定义的别名,不可重复
  -keypass password123!@#  //设置密钥对的密码,这个密码用于保护私钥
  -keyalg RSA  //指定生成的密钥对算法为RSA
  -keysize 2048  //指定RSA密钥的大小为2048位
  -validity 9999  //指定密钥的有效期 天
  -keystore D:\dataKeystore\dataKeystore.keystore  //指定密钥库的路径和文件名
  -storepass admin-test  //密钥库的密码,用于保护密钥库中的密钥对

#创建keystore
.\keytool.exe -genkeypair -alias dataKeystor -keypass password123!@# -keyalg RSA -keysize 2048 -validity 9999 -keystore D:\keystore\dataKeystor.keystore -storepass admin-test

#查看密匙库
 .\keytool.exe -list -rfc -keystore D:\keystore\dataKeystore.keystore -storepass admin-test


代码方式创建keystore:

    private static final int keysize = 2048;
    private static final String commonName = "www.baidi.com";
    private static final String organizationalUnit = "baidu";
    private static final String organization = "baidu";
    private static final String city = "hebei";
    private static final String state = "baoding";
    private static final String country = "CN";
    private static final long validity = 3650; //十年
    private static final String alias = "test";
    private static final char[] keyPassword = "1231312".toCharArray();
    private static final char[] storePassword = "1231231".toCharArray();
    private static final String path = CreateKeystore.class.getClassLoader().getResource(".").getPath();

    public static void main(String[] args) {
        createKeystore();
    }

    public static void createKeystore(){
        //获取文件地址
         try {
            KeyStore ks = KeyStore.getInstance("JKS");
            ks.load(null, null);

            CertAndKeyGen keypair = new CertAndKeyGen("RSA", "SHA1WithRSA", null);
            X500Name x500Name = new X500Name(commonName, organizationalUnit, organization, city, state, country);
            keypair.generate(keysize);

            PrivateKey privateKey = keypair.getPrivateKey();
            X509Certificate[] chain = new X509Certificate[1];
            chain[0] = keypair.getSelfCertificate(x500Name, new Date(), (long)validity*24*60*60);

            FileOutputStream fos = new FileOutputStream(path+"OEM_Keystore.keystore");
            ks.setKeyEntry(alias, privateKey, keyPassword, chain);
            ks.store(fos, storePassword);
            fos.close();
            System.out.println("create Success");
        } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException |
                 NoSuchProviderException | InvalidKeyException | SignatureException e ) {
            e.printStackTrace();
        }
    }

 java使用Keystore: 注意 导出公钥一般格式为:public_key.pem 私钥为(一般不可导出,仅为导出时示范):private_key.pem ,PEM(Privacy-Enhanced Mail)文件是一种常用的证书格式,通常用于存储加密证书、私钥和其他相关证书。PEM文件使用Base64编码表示,并包含"-----BEGIN CERTIFICATE-----"和"-----END CERTIFICATE-----"之间的文本块

package com.gdc.encryption.util;

/**
 *  公私钥获取,加解密工具类
 * @owner jiangliu
 * @Date: 2024/4/17 10:32
 */
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.core.io.ClassPathResource;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.sql.SQLOutput;

public class KeyStoreUtil {

    /**
     * Java密钥库(Java Key Store,JKS)KEY_STORE
     */
    public static final String KEY_STORE = "JKS";

    public static final String X509 = "X.509";

    /**
     * keystore基本信息,本示例放在springboot resources目录下。
     * @param
     */
    public static final String keystorePath= KeyStoreUtil.class.getClassLoader().getResource("OEM_Keystore.keystore").getPath();;

    private static final String alias = "test";

    private static final String storePass = "123456";

    private static final String keyPass = "123456";

    /**
     * 公加私解
     * 私加公解
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {

        String strPrivateKey = getStrPrivateKey();
 
        String strPublicKey = getStrPublicKey();

        // 原始字符串
        String message = "我是测试原始内容";
        System.out.println("原始数据:"+message);
        String messageEn = publicKeyEncrypt(message, strPublicKey);
        System.out.println("公钥加密后内容:" + messageEn);
        String messageDe = privateKeyDecrypt(messageEn, strPrivateKey);
        System.out.println("私钥解密后内容:" + messageDe);

        System.out.println("=====================");

        //私钥加密,公钥解密
        String s = privateKeyEncrypt(message, strPrivateKey);
        System.out.println("私钥加密后内容:"+s);
        String s1 = publicKeyDecrypt(s, strPublicKey);
        System.out.println("公钥解密后内容:"+s1);
    }

    /**
     * BASE64解密
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decryptBASE64(String key) throws Exception {

        return(new BASE64Decoder()).decodeBuffer(key);

    }

    /**
     * BASE64加密
     * @param key
     * @return
     * @throws Exception
     */
    public static String encryptBASE64(byte[] key) throws Exception {

        return(new BASE64Encoder()).encodeBuffer(key).replace("\r","").replace("\n","");

    }

    /**
     * 获得KeyStore
     *
     * @param keyStorePath
     * @param password
     * @return
     * @throws Exception
     */
    private static KeyStore getKeyStore(String keyStorePath, String password)

            throws Exception {

        FileInputStream is = new FileInputStream(keyStorePath);

        KeyStore ks = KeyStore.getInstance(KEY_STORE);

        ks.load(is, password.toCharArray());

        is.close();

        return ks;

    }

    /**
     * 由KeyStore获得私钥
     *
     * @param keyStorePath
     * @param alias
     * @param storePass
     * @return
     */
    private static PrivateKey getPrivateKey(String keyStorePath, String alias, String storePass, String keyPass) throws Exception {

        KeyStore ks = getKeyStore(keyStorePath, storePass);

        PrivateKey key = (PrivateKey) ks.getKey(alias, keyPass.toCharArray());

        return key;

    }

    /**
     * 由Certificate获得公钥
     *
     * @param keyStorePath KeyStore路径
     * @param alias        别名
     * @param storePass    KeyStore访问密码
     */
    private static PublicKey getPublicKey(String keyStorePath, String alias, String storePass) throws Exception {

        KeyStore ks = getKeyStore(keyStorePath, storePass);

        PublicKey key = ks.getCertificate(alias).getPublicKey();

        return key;

    }

    /**
     * 从KeyStore中获取公钥,并经BASE64编码
     *
     */
    public static String getStrPublicKey() throws Exception {

        PublicKey key = getPublicKey(keystorePath, alias, storePass);

        String strKey = encryptBASE64(key.getEncoded());

        return strKey;

    }

    /**
     * 获取经BASE64编码后的私钥
     *
     * @return
     * @throws Exception
     * @author 奔跑的蜗牛
     */

    public static String getStrPrivateKey() throws Exception {

        PrivateKey key = getPrivateKey(keystorePath, alias, storePass, keyPass);

        String strKey = encryptBASE64(key.getEncoded());

        return strKey;

    }

    /**
     * RSA公钥加密
     *
     * @param str       加密字符串
     * @param publicKey 公钥
     * @return 密文
     * @throws Exception 加密过程中的异常信息
     */
    public static String publicKeyEncrypt(String str, String publicKey) throws Exception {
        //base64编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").
                generatePublic(new X509EncodedKeySpec(decoded));
        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
        return outStr;
    }

    /**
     * RSA私钥解密
     *
     * @param str
     * @param privateKey 私钥
     * @return 铭文
     * @throws Exception 解密过程中的异常信息
     */
    public static String privateKeyDecrypt(String str, String privateKey) throws Exception {
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
        //base64编码的私钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
                .generatePrivate(new PKCS8EncodedKeySpec(decoded));
        //RSA解密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        String outStr = new String(cipher.doFinal(inputByte), StandardCharsets.UTF_8);
        return outStr;
    }

    /**
     * RSA私钥解密
     *
     * @param bytes
     * @param privateKey 私钥
     * @return 铭文
     * @throws Exception 解密过程中的异常信息
     */
    public static byte[] privateKeyDecryptBytes(byte[] bytes, String privateKey) throws Exception {
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
                .generatePrivate(new PKCS8EncodedKeySpec(decoded));
        //RSA解密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        byte[] bytes1 = cipher.doFinal(bytes);
        return bytes1;
    }


    /**
     * RSA私钥加密
     *
     * @param str
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String privateKeyEncrypt(String str, String privateKey) throws Exception {
        //base64编码的公钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        PrivateKey priKey = KeyFactory.getInstance("RSA").
                generatePrivate(new PKCS8EncodedKeySpec(decoded));
        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, priKey);
        String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes()));
        return outStr;
    }

    /**
     * RSA公钥解密
     *
     * @param str
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static String publicKeyDecrypt(String str, String publicKey) throws Exception {
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
        //base64编码的私钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        PublicKey pubKey =  KeyFactory.getInstance("RSA")
                .generatePublic(new X509EncodedKeySpec(decoded));
        //RSA解密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, pubKey);
        String outStr = new String(cipher.doFinal(inputByte));
        return outStr;
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值