keytool生成RSA证书

  生成RSA公钥私钥不仅可以通过代码去进行实现,还可以通过keytool去创建证书,进而用代码去读取证书中的公钥和私钥去进行加解密的操作。

1.keytool生成RSA证书

    1.管理员身份进入dos环境    运行 keytool  -genkey    

注意红框部分,生成的证书将会在这个路径下面

运行后,会让你输入一系列名称,输入后尽量记住别输错,后面生成证书会用到,另外,会让你输入两个六位数的密码,两个密码可以一致。

2.运行    keytool -genkey -alias ceshi -keyalg RSA -keysize 2048 -keystore mykeystore -validity 400

此行命令解释为:将使用RSA算法生成2048位的公钥/私钥对及整数,密钥长度为2048位,证书有效期为400天。使用的密钥库为mykeystore文件,别名为ceshi(后面可以直接用这个别名来代表mykeystore文件)。

生成成功会让你输入密码,用之前的密码输入即可。

3.导出公钥证书   keytool -export -alias ceshi -keystore mykeystore -file ceshi.cer

 解释为:keytool -export -alias 别名 -keystore 文件名 -file 证书名称       导出别名为ceshi的文件keystore,取一个证书名字.cer(此处证书的存放路径为上文截图的红框部分),不论是否报错,都去证书路径处查看是否有证书。

4.代码里面读取证书路径,从而拿到相应的rsa的公钥私钥去进行加解密的操作。

此处为我的证书路径,代码中无论读取哪个都行,读取第二个的时候会读取最新的数据(每次最新的数据会覆盖).

代码中识别本地生成的rsa证书,并进行加解密(公钥加密私钥解密),加密和验签的操作,基本符合我们的需求

package com.youfuli.apicenter.utils;

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

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.security.*;
import java.security.cert.Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class RSAUtils {

    public static final String CHARSET = "UTF-8";
    public static final String RSA_ALGORITHM = "RSA";



    /**
     * 验签
     */
    public static boolean verify(byte[] message, byte[] signMessage, PublicKey publicKey, 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.initVerify(publicKey);
        signature.update(message);
        return signature.verify(signMessage);
    }

    /**
     * 签名
     */
    public static byte[] 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);
        return signature.sign();
    }

    //公钥加密
    public static byte[] encrypt(byte[] content, PublicKey publicKey) throws Exception{
        Cipher cipher=Cipher.getInstance("RSA");//java默认"RSA"="RSA/ECB/PKCS1Padding"
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(content);
    }

    //私钥解密
    public static byte[] decrypt(byte[] content, PrivateKey privateKey) throws Exception{
        Cipher cipher=Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(content);
    }

    public static void main(String[] args) throws  Exception {
        FileInputStream in = new FileInputStream("C:\\Windows\\System32\\mykeystore");
        KeyStore keyStore = KeyStore.getInstance("JKS");
        keyStore.load(in,"135246".toCharArray());
        Enumeration aliasEnum = keyStore.aliases();
        String keyAlias = "" ;
        while (aliasEnum.hasMoreElements()) {
            keyAlias = (String) aliasEnum.nextElement();
            System.out.println("别名"+keyAlias);
        }

        Certificate ce = keyStore.getCertificate(keyAlias);
        PublicKey publicKey = keyStore.getCertificate(keyAlias).getPublicKey();
        //System.out.println("publicKey"+publicKey);
        String publick = Base64.encodeBase64String(publicKey.getEncoded());
        System.out.println("public"+publick);
        //加载私钥,这里填私钥密码
        PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) keyStore.getEntry(keyAlias,
                new KeyStore.PasswordProtection("135246".toCharArray()))).getPrivateKey();
        //加载私钥另一写法
        //PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias, "123456".toCharArray());

        //base64输出私钥
        String strKey = Base64.encodeBase64String(privateKey.getEncoded());

        //测试签名
        String sign = Base64.encodeBase64String(sign("测试msg".getBytes(),privateKey,"SHA1withRSA",null));

        byte[] jiami = encrypt("01510136|15000364728".getBytes(),publicKey);
        System.out.println("加密后"+Base64.encodeBase64String(jiami));
        //测试验签
        boolean verfi = verify("01510136|15000364728".getBytes(),Base64.decodeBase64(sign), publicKey,"SHA1withRSA",null);
        //String s = privateDecrypt("我是一个人",privateKey);
        byte[] jiemi = decrypt(jiami,privateKey);
        System.out.println("解密后"+new String(jiemi));
    }
}

整体的运行效果如下图显示

很明显,通过将byte[]转化为base64编码后,然后将编码后的文件进行了解密,这里要注意的是,我这里解密的未进行编码的加密数据,所以实际大家使用的时候记得base64解码后再进行解密。最终也是成功的解出了最后的加密数据,当然,你要是想进行签名操作,也可以调用验签和签名的方法,我在main方法中也有进行调用。

其实也折腾了很久,比如会碰到RSAPublicKey和PublicKey的区别,其实只是不同包名下面的不同方法,分别调用即可。

麻烦大家使用注明出处有哟,大家一起进步成长!

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值