(keytool)自签名SSL证书(免费)以及私钥签名、公钥验签

本文主要介绍keytool自签名SSL证书(免费)以及私钥签名、公钥验签流程,点击查看keytool CA签名SSL证书(收费)

最近给银行做一个系统,虽说是给行内使用的,但是系统要同时支持内外网方式登录,采用https(http+ssl)传输协议,经过SSL加密信息,防止用户信息被截获。

因此花了一段时间研究这方面的知识,主要从JDK自带keytool入手,研究如何通过keytool最终得到自签名SSL证书。

百度百科【CA】
证书颁发机构(CA, Certificate Authority)即颁发数字证书的机构。是负责发放和管理数字证书的权威机构,并作为电子商务交易中受信任的第三方,承担公钥体系中公钥的合法性检验的责任。科

百度百科【SSL】
Secure Sockets Layer 安全套接层及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。

对于JDK自带的keytool指令,不论Windows还是Linux,该指令文件存放在JAVA_HOME/bin目录下,使用的前提是系统已搭建好JDK环境且配置JAVA环境变量。

正文以Windows操作为例,D:/keys/是我个人证书文件存放路径,实际请自行替换相关路径。

目录

一、生成密钥库

二、证书库导出公钥证书

​三、私钥签名、公钥验签


一、生成密钥库

keytool -genkeypair -alias mykeystore -keyalg RSA -keysize 2048 -keypass mypassword -sigalg SHA256withRSA -dname "cn=www.justinqin.com,ou=justinqin,o=qjg,l=Shenzhen,st=Guangdong,c=CN" -validity 1095 -keystore D:/keys/mykeystore.keystore -storetype JKS -storepass mypassword

==================参数含义=======================
-genkeypair
非对称密钥(密钥对,私钥签名、公钥验签),对称密钥为-gendeskey(单个密钥)

-alias mykeystore
证书库别名为mykeystore

-keyalg RSA
加密算法为RSA,加密算法可以分为对称加密、不对称加密和不可逆加密算法
对称加密算法:加解密都用的同一把密钥,如DES、AES
不对称加密算法:使用密钥对即公钥、私钥进行加解密,如RSA SHS
不可逆加密算法:加密过程中不需要密钥,明文加密成密文后不可逆,如MD5
MD5、SHS的加密都是用了哈希加密算法

-keysize 2048
密钥长度,位数越大越安全,但同时加解密时间成正比增长

-keypass mypassword
私钥密码为mypassword

-sigalg SHA256withRSA
签名算法为SHA256withRSA
keyalg=RSA时,sigalg可选MD5withRSA、SHA1withRSA、SHA256withRSA、SHA384withRSA、SHA512withRSA
keyalg=DSA时,sigalg可选SHA1withDSA、SHA256withDSA

 -dname "cn=www.justinqin.com,ou=justinqin,o=qjg,l=Shenzhen,st=Guangdong,c=CN"
证书相关信息
CN=名字与姓氏/域名
OU=组织单位名称
O=组织名称
L=城市或区域名称
ST=州或省份名称
C=单位的两字母国家代码

-keystore D:/keys/mykeystore.keystore
生成的证书库文件为mykeystore.keystore,存储位置D:/keys/

-validity 1095
证书有效天数为3年=1095

-storetype JKS
证书库类型为JKS,JDK1.9以前默认JKS,JDK1.9及以后默认PKCS12

-storepass mypassword
证书库密码为mypassword


二、证书库导出公钥证书

keytool -export -alias mykeystore -keystore D:/keys/mykeystore.keystore -storepass mypassword -file D:/keys/publickey.cer

=========================证书查看相关指令==============
证书库查看

keytool -list -v -keystore D:/keys/mykeystore.keystore -storepass mypassword

(keytool)自签名SSL证书(免费)以及私钥签名、公钥验签_第1张图片

公钥证书查看

keytool -printcert -file D:/keys/publickey.cer

(keytool)自签名SSL证书(免费)以及私钥签名、公钥验签_第2张图片
三、私钥签名、公钥验签

package com.justin.key;

import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Enumeration;

import org.apache.commons.codec.binary.Base64;

import sun.misc.BASE64Encoder;

/**
 * 从证书库获取公私钥、公钥证书获取公钥、私钥签名、公钥验签 
 * @author justinqin
 *
 */
public class GenKeyStoreTest {
    
    public static String KEYSTORD_FILE = "D:\\keys\\mykeystore.keystore";//证书库文件
    public static String PUB_CER_FILE = "D:\\keys\\publickey.cer";//公钥证书
    public static String KEYSTORD_PASSWORD = "mypassword";//证书库密码
    public static String PRIKEY_PASSWORD = "mypassword";//私钥密码
    public static String KEYSTORD_ALIAS = "mykeystore";//证书库别名:有多个别名时,引用参数指定具体别名
    public static String CONTENT = "内容content";
    
    public static String SIGALG_MD5WITHRSA ="MD5withRSA"; //sigalg(签名算法):MD5withRSA
    public static String SIGALG_SHA1WITHRSA ="SHA1withRSA"; //sigalg(签名算法):SHA1withRSA
    public static String SIGALG_SHA256WITHRSA ="SHA256withRSA"; //sigalg(签名算法):SHA256withRSA
    public static String SIGALG_SHA384WITHRSA ="SHA384withRSA"; //sigalg(签名算法):SHA384withRSA
    public static String SIGALG_SHA512WITHRSA ="SHA512withRSA"; //sigalg(签名算法):SHA256withRSA
    
    public static String STORE_TYPE_JKS  ="JKS";
    
    
    public static void main(String[] args) throws Exception {
        
        //====================证书库中获取私钥、公钥,公钥证书中获取公钥========================
        KeyStore keyStore = getKeyStore(KEYSTORD_FILE);
        Certificate certificate = keyStore.getCertificate(KEYSTORD_ALIAS);
        //私钥
        PrivateKey privateKey = (PrivateKey) keyStore.getKey(KEYSTORD_ALIAS, PRIKEY_PASSWORD.toCharArray());
        //公钥(从证书库文件中)
        PublicKey publicKey = certificate.getPublicKey();
        //公钥(从公钥证书中获取)
        PublicKey cerPublicKey = getPublicKeyFromPubCerFile(PUB_CER_FILE);
        
        
        //====================base64位输出公私钥========================
        base64PrintKey(privateKey.getEncoded(),"证书库","私钥");
        String base64KeystorePubKey = base64PrintKey(publicKey.getEncoded(),"证书库","公钥");
        String base64CerPubKey = base64PrintKey(cerPublicKey.getEncoded(),"公钥证书","公钥");
        System.out.println("证书库中的公钥和公钥证书中的公钥是否相同:" + base64KeystorePubKey.equals(base64CerPubKey));

        //====================用私钥对明文进行签名========================
        String md5Sign = sign(CONTENT.getBytes(),privateKey,SIGALG_MD5WITHRSA,null);
        String sha1Sign = sign(CONTENT.getBytes(),privateKey,SIGALG_SHA1WITHRSA,null);
        String sha256Sign = sign(CONTENT.getBytes(),privateKey,SIGALG_SHA256WITHRSA,null);
        String sha384Sign = sign(CONTENT.getBytes(),privateKey,SIGALG_SHA384WITHRSA,null);
        String sha512Sign = sign(CONTENT.getBytes(),privateKey,SIGALG_SHA512WITHRSA,null);
        
        
        //====================公钥验签========================
        verify(CONTENT.getBytes(),Base64.decodeBase64(md5Sign), publicKey,SIGALG_MD5WITHRSA,null);
        verify(CONTENT.getBytes(),Base64.decodeBase64(sha1Sign), publicKey,SIGALG_SHA1WITHRSA,null);
        verify(CONTENT.getBytes(),Base64.decodeBase64(sha256Sign), publicKey,SIGALG_SHA256WITHRSA,null);
        verify(CONTENT.getBytes(),Base64.decodeBase64(sha384Sign), publicKey,SIGALG_SHA384WITHRSA,null);
        verify(CONTENT.getBytes(),Base64.decodeBase64(sha512Sign), publicKey,SIGALG_SHA512WITHRSA,null);
    }
    
    /**
     * base64输出公私钥
     * @param keyEncoded
     * @param keyFile
     * @param keyType
     * @return
     */
    private static String base64PrintKey(byte[] keyEncoded,String keyFile,String keyType) {
        String base64Key = new BASE64Encoder().encode(keyEncoded);
        System.out.println("base64输出" + keyFile + "中的"+ keyType + ":");
        System.out.println(base64Key);
        return base64Key;
    }

    
    /**
     * 获取证书库对象
     * @param keystoreFile
     * @return
     * @throws Exception
     */
    private static KeyStore getKeyStore(String keystoreFile) throws Exception {
        FileInputStream keystoreIs = new FileInputStream(new File(KEYSTORD_FILE));
        KeyStore keyStore = KeyStore.getInstance(STORE_TYPE_JKS);
        keyStore.load(keystoreIs, KEYSTORD_PASSWORD.toCharArray());
        keystoreIs.close();
        return keyStore;
    }

    /**
     * 签名:使用私钥进行签名
     * @param message
     * @param privateKey
     * @param algorithm
     * @param provider
     * @return
     * @throws Exception
     */
    public static String sign(byte[] message, PrivateKey privateKey, String algorithm, String provider) throws Exception {
        Signature signature;
        if (null == provider || provider.length() == 0) {
            signature = Signature.getInstance(algorithm);
        } else {
            signature = Signature.getInstance(algorithm, provider);
        }
        signature.initSign(privateKey);
        signature.update(message);
        byte[] sign = signature.sign();
        return Base64.encodeBase64String(sign);
    }
    
    /**
     * 验签:使用公钥进行验签
     * @param message
     * @param signMessage
     * @param publicKey
     * @param algorithm
     * @param provider
     * @return
     * @throws Exception
     */
    public static boolean verify(byte[] message, byte[] signMessage, PublicKey publicKey, String algorithm,
                                 String provider) throws Exception {
        Signature signature;
        boolean verifyResult;
        if (null == provider || provider.length() == 0) {
            signature = Signature.getInstance(algorithm);
        } else {
            signature = Signature.getInstance(algorithm, provider);
        }
        signature.initVerify(publicKey);
        signature.update(message);
        verifyResult = signature.verify(signMessage);
        System.out.println(algorithm+ "验签结果:" + verifyResult);
        return verifyResult;
    }
    
    /**
     * 从公钥证书中获取公钥
     * @param pubCerFile
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKeyFromPubCerFile(String pubCerFile) throws Exception{
        FileInputStream cerIs = new FileInputStream(new File(pubCerFile));
        CertificateFactory cer = CertificateFactory.getInstance("X.509");
        Certificate cerCertificate = cer.generateCertificate(cerIs);
        cerIs.close();
        PublicKey cerPublicKey = cerCertificate.getPublicKey();
        return cerPublicKey;
    }
    
    
    /**
     * 证书库获取别名:证书库只有一个别名时,该方法能取到默认别名,有多个别名时,会被覆盖,需引用参数指定具体别名
     * 
     * @param pubCerFile
     * @return
     * @throws Exception
     */
    public static String getAliasByKeystore(KeyStore keyStore) throws Exception{
      Enumeration aliasEnum = keyStore.aliases();
      String keystoreAlias=null;
      while (aliasEnum.hasMoreElements()) keystoreAlias = (String) aliasEnum.nextElement();
      return keystoreAlias;
    }
    
}


========================测试结果====================

base64输出证书库中的私钥:
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCA1U01yh9UIb2JYFgBvJO6My2n
UKVOz5Squ25T9Hw6nJVemZrwmRIRm1lYEE0Zp92uxelQZfMerERoRFEZwdh8TwLnxBfyR9YRC99F
DsRty2m2Dkwvkr3EI70ruHANsaFmS3ReSw4O6ZgpvAiboC87o49AQe3rv+ICHIbbjHUZy/bIYML2
24AbjOrOajqC3fEl7ZwHn94lEAf2EXOFU5B/qfk13YqdZcb46txwbtVWdHIT0PzU2+e1qZU655ZR
jO4kVLyPKURfelyTemTmezI5o3RBiKU3psLsMnC69DzA6F66+FAYt5IiX7EWvfXe0Oj6AU2LKVnT
V+3g9ZBNvsG/AgMBAAECggEAV0QkkJLgtbRFFpDUDBkYV7/i5LqTvtaM9TkQen3YyDrYUsPpV5/X
xWVdF3GzR/WVC5WzfGoSTGyTyay84p2TbmB2r1b8gXh3YASSr8xY8aYfbNoycOcM85bhxIOiIyR3
Fzt1D4n3c9J2544epovScqtPlU8TQeUvyg5Yqs5xY473CuRezAGz6OGBJ/PT4JlwDsOf5vOx2U5F
8+4fbkvACz14uM49vSmFeoz2VA3W8/+WrJFIJc+x7qIJFecfRxE4i+1f94OSLFn0fYciPV07jZt4
bZMLc2iAIJaCUDbJUTDCBH4J0wk4qmjJhrR/3M+3VLKPLRhpW3ezHcyB46OfwQKBgQC10WcQ1INW
hf4+UlT2u97LqeyKUI9sdFa0GmCWxEfHNxiycvqbevqon63rxEcTD2GS2aqzHGSLnp/WcawKt2Xr
GEwf/jvtVypVPcQVrkRIoFw1aynbazVy11oYACAUheqenCtS8NFpCVSBEMqA4c//GaRZInvYga9z
zq7sbEYKvQKBgQC1Zbl3io8nuVOQVZQFJbnlFF1wIy6/855APQLS5udxIFpC5VrYjhm44B7+aii1
21uz7dfsrDIFabv21vq+ITssxNw1MmCS9ihwwUbZmNK0BTFAK1RywHiU6GEeVLoVFbPe6Ghs7vOc
RksPo8nOTAjHV6fmnd+GGDbyujUcYhAEKwKBgB1FfDlabValtdvkt2cNsf3J+pn+BEkqpbbTNE+x
g/jPpvs7xZr4fphdNMvrSqIH7OaOgovZe1p7DDKjFFaZViA2RjM0ZAN+8ALPMd1ns/iZUJ8NBK0d
ono9r3SDuKZ1NOOaMuNkf+JQLTmmMWP0dt8UCsCK67NclZmoYcMQX2plAoGBAKOtcUezR+8BI6zF
+3UVkIJq+NDZfjKH4VB3fNfOsCF8ntVj3LAwsHcIDA9mvOszTrCxOTd+PPhzar6VRtVOaPXBgC2k
Ek4pPV5Yl9R6OA1l7gXH00Bj+anrcM6MhwfFeHL3ZFp+1mQ5bTtkgBDcvMMajg7ifzGhIdutN4Uv
2uHXAoGAa3wj3zviGCaDh2CRsOgs62fR+nu0ck+OvqMDUoQN4qKitoaqpixgLPz99byFPbD65Z80
t61mG1k0rp5OXVSr7QnZmtQ+rh763i7gg6AEYNDnPH116ozY+Klf2Rl9CIs0G8/UHTGO1/Q5ZqD7
0xtrMMwe2Qw6fgsH4kTP6iwIml0=
base64输出证书库中的公钥:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgNVNNcofVCG9iWBYAbyTujMtp1ClTs+U
qrtuU/R8OpyVXpma8JkSEZtZWBBNGafdrsXpUGXzHqxEaERRGcHYfE8C58QX8kfWEQvfRQ7Ebctp
tg5ML5K9xCO9K7hwDbGhZkt0XksODumYKbwIm6AvO6OPQEHt67/iAhyG24x1Gcv2yGDC9tuAG4zq
zmo6gt3xJe2cB5/eJRAH9hFzhVOQf6n5Nd2KnWXG+OrccG7VVnRyE9D81NvntamVOueWUYzuJFS8
jylEX3pck3pk5nsyOaN0QYilN6bC7DJwuvQ8wOheuvhQGLeSIl+xFr313tDo+gFNiylZ01ft4PWQ
Tb7BvwIDAQAB
base64输出公钥证书中的公钥:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgNVNNcofVCG9iWBYAbyTujMtp1ClTs+U
qrtuU/R8OpyVXpma8JkSEZtZWBBNGafdrsXpUGXzHqxEaERRGcHYfE8C58QX8kfWEQvfRQ7Ebctp
tg5ML5K9xCO9K7hwDbGhZkt0XksODumYKbwIm6AvO6OPQEHt67/iAhyG24x1Gcv2yGDC9tuAG4zq
zmo6gt3xJe2cB5/eJRAH9hFzhVOQf6n5Nd2KnWXG+OrccG7VVnRyE9D81NvntamVOueWUYzuJFS8
jylEX3pck3pk5nsyOaN0QYilN6bC7DJwuvQ8wOheuvhQGLeSIl+xFr313tDo+gFNiylZ01ft4PWQ
Tb7BvwIDAQAB
证书库中的公钥和公钥证书中的公钥是否相同:true
MD5withRSA验签结果:true
SHA1withRSA验签结果:true
SHA256withRSA验签结果:true
SHA384withRSA验签结果:true
SHA512withRSA验签结果:true

 

==========拷贝得到的公私钥字符串,首尾格式化

公钥首尾:

-----BEGIN PUBLIC KEY-----
公钥字符串
-----END PUBLIC KEY-----

私钥首尾:

-----BEGIN RSA PRIVATE KEY-----
私钥字符串
-----END RSA PRIVATE KEY-----

==========在线RSA公私密钥校验、RSA公私密钥检查 http://tool.chacuo.net/cryptrsakeyvalid

(keytool)自签名SSL证书(免费)以及私钥签名、公钥验签_第3张图片

 

你可能感兴趣的:(系统运维)