zoukankan      html  css  js  c++  java
  • openssl 制作证书和签名java方法

    Win32OpenSSL_Light-0_9_8k.exe

    1. 生成不含密码保护的私钥:
    openssl genrsa -out private-rsa.key 1024

    2. 生成证书
    openssl req -new -x509 -key private-rsa.key -days 750 -out public-rsa.cer


    3. 生成Keystore
    3.1. 生成PKCS12 格式Keystore
    openssl pkcs12 -export -name test-alias -in public-rsa.cer -inkey private-rsa.key -out 99bill-rsa.pfx


    pfx格式证书转换为pem格式命令
    openssl pkcs12 -in 99bill-rsa.pfx -passin pass:生成证书设置的密码 -nodes -out 99bill-rsa.pem

    private-rsa.pfx

    public-rsa.cer

    附:签名方法

    package com.verify.cert;

    public class CertUtil {

    /**
    * 对字符串进行签名
    *
    * @param TobeSigned
    * 需要进行签名的字符串
    * @param KeyFile
    * PFX证书文件路径
    * @param PassWord
    * 私钥保护密码
    * @return 签名成功返回true(从LastResult属性获取结果),失败返回false(从LastErrMsg属性获取失败原因)
    */
    public static String SignMsg(final String TobeSigned, final String KeyFile, final String PassWord) throws Exception {
    CryptNoRestrict cryptNoRestrict = new CryptNoRestrict();
    cryptNoRestrict.SignMsg(TobeSigned, KeyFile, PassWord);
    return cryptNoRestrict.lastSignMsg;
    }

    /**
    * 验证签名
    *
    * @param TobeVerified
    * 待验证签名的密文
    * @param PlainText
    * 待验证签名的明文
    * @param CertFile
    * 签名者公钥证书
    * @return 验证成功返回true,失败返回false(从LastErrMsg属性获取失败原因)
    */
    public static boolean VerifyMsg(String TobeVerified, String PlainText, String CertFile) throws Exception {
    CryptNoRestrict cryptNoRestrict = new CryptNoRestrict();
    return cryptNoRestrict.VerifyMsg(TobeVerified, PlainText, CertFile);
    }

    public static void main(String[] args) {
    try {
    String a = "100|123123122222222222222";
    String b = SignMsg(a, "com/verify/cert/private-rsa.pfx", "123456");
    System.err.println(b);
    System.err.println(VerifyMsg(b, a, "com/verify/cert/public-rsa.cer"));


    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    }

    package com.verify.cert;

    public interface CryptInf {
    public boolean VerifyMsg(String TobeVerified, String PlainText, String CertFile) throws Exception;

    public boolean SignMsg(String TobeSigned, String KeyFile, String PassWord) throws Exception;

    public String getLastSignMsg();
    }

    /**
    *
    */
    package com.verify.cert;

    import java.io.InputStream;
    import java.security.KeyStore;
    import java.security.Provider;
    import java.security.Signature;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    import java.security.interfaces.RSAPrivateCrtKey;
    import java.security.interfaces.RSAPublicKey;
    import java.util.Enumeration;

    import org.bouncycastle.jce.provider.BouncyCastleProvider;

    /**
    * @author Administrator
    *
    */
    public class CryptNoRestrict implements CryptInf {
    public static Provider provider = new BouncyCastleProvider();

    /**
    * 构造函数
    */
    public CryptNoRestrict() {
    }

    public CryptNoRestrict(String encoding) {
    this.encoding = encoding;
    }

    private String encoding = "GBK";

    /**
    * 取出上次调用加密、解密、签名函数成功后的输出结果
    */
    protected String lastResult;

    /**
    * 返回上一次签名结果
    */
    protected String lastSignMsg;

    /**
    * 对字符串进行签名
    *
    * @param TobeSigned
    * 需要进行签名的字符串
    * @param KeyFile
    * PFX证书文件路径
    * @param PassWord
    * 私钥保护密码
    * @return 签名成功返回true(从LastResult属性获取结果),失败返回false(从LastErrMsg属性获取失败原因)
    */
    public boolean SignMsg(final String TobeSigned, final String KeyFile, final String PassWord) throws Exception {

    ClassLoader cl = CryptNoRestrict.class.getClassLoader();
    InputStream fiKeyFile = cl.getResourceAsStream(KeyFile);
    // 传入绝对路径
    // FileInputStream fiKeyFile = null;
    // fiKeyFile = new FileInputStream(KeyFile);

    boolean result = false;
    this.lastSignMsg = "";
    KeyStore ks = KeyStore.getInstance("PKCS12");

    try {
    ks.load(fiKeyFile, PassWord.toCharArray());
    } catch (Exception ex) {
    if (fiKeyFile != null)
    fiKeyFile.close();
    throw ex;
    }
    Enumeration myEnum = ks.aliases();
    String keyAlias = null;
    RSAPrivateCrtKey prikey = null;
    // keyAlias = (String) myEnum.nextElement();
    /* IBM JDK必须使用While循环取最后一个别名,才能得到个人私钥别名 */
    while (myEnum.hasMoreElements()) {
    keyAlias = (String) myEnum.nextElement();
    // System.out.println("keyAlias==" + keyAlias);
    if (ks.isKeyEntry(keyAlias)) {
    prikey = (RSAPrivateCrtKey) ks.getKey(keyAlias, PassWord.toCharArray());
    break;
    }
    }
    if (prikey == null) {
    result = false;
    throw new Exception("没有找到匹配私钥");
    } else {
    Signature sign = Signature.getInstance("SHA1withRSA");
    sign.initSign(prikey);
    sign.update(TobeSigned.getBytes(encoding));
    byte signed[] = sign.sign();
    byte sign_asc[] = new byte[signed.length * 2];
    Hex2Ascii(signed.length, signed, sign_asc);
    this.lastResult = new String(sign_asc);
    this.lastSignMsg = this.lastResult;
    result = true;
    }
    return result;
    }

    /**
    * 验证签名
    *
    * @param TobeVerified
    * 待验证签名的密文
    * @param PlainText
    * 待验证签名的明文
    * @param CertFile
    * 签名者公钥证书
    * @return 验证成功返回true,失败返回false(从LastErrMsg属性获取失败原因)
    */
    public boolean VerifyMsg(String TobeVerified, String PlainText, String CertFile) throws Exception {
    boolean result = false;
    ClassLoader cl = CryptNoRestrict.class.getClassLoader();
    InputStream certfile = cl.getResourceAsStream(CertFile);
    // 传入绝对路径
    // FileInputStream certfile = null;
    // certfile = new FileInputStream(CertFile);
    CertificateFactory cf = CertificateFactory.getInstance("X.509");

    X509Certificate x509cert = null;
    try {
    x509cert = (X509Certificate) cf.generateCertificate(certfile);
    } catch (Exception ex) {
    if (certfile != null)
    certfile.close();
    throw ex;
    }

    RSAPublicKey pubkey = (RSAPublicKey) x509cert.getPublicKey();
    Signature verify = Signature.getInstance("SHA1withRSA");
    verify.initVerify(pubkey);
    byte signeddata[] = new byte[TobeVerified.length() / 2];
    Ascii2Hex(TobeVerified.length(), TobeVerified.getBytes(encoding), signeddata);
    verify.update(PlainText.getBytes(encoding));
    if (verify.verify(signeddata)) {
    result = true;
    } else {
    result = false;
    // throw new Exception("验签失败");
    }
    return result;
    }

    /**
    * 返回上次调用加密、解密、签名函数成功后的输出结果
    *
    * @return 返回上次调用加密、解密、签名函数成功后的输出结果
    */
    public String getLastResult() {
    return this.lastResult;
    }

    /**
    * 返回上一次签名结果
    *
    * @return 签名结果
    */
    public String getLastSignMsg() {
    return this.lastSignMsg;
    }

    /**
    * 将十六进制数据转换成ASCII字符串
    *
    * @param len
    * 十六进制数据长度
    * @param data_in
    * 待转换的十六进制数据
    * @param data_out
    * 已转换的ASCII字符串
    */
    private static void Hex2Ascii(int len, byte data_in[], byte data_out[]) {
    byte temp1[] = new byte[1];
    byte temp2[] = new byte[1];
    for (int i = 0, j = 0; i < len; i++) {
    temp1[0] = data_in[i];
    temp1[0] = (byte) (temp1[0] >>> 4);
    temp1[0] = (byte) (temp1[0] & 0x0f);
    temp2[0] = data_in[i];
    temp2[0] = (byte) (temp2[0] & 0x0f);
    if (temp1[0] >= 0x00 && temp1[0] <= 0x09) {
    (data_out[j]) = (byte) (temp1[0] + '0');
    } else if (temp1[0] >= 0x0a && temp1[0] <= 0x0f) {
    (data_out[j]) = (byte) (temp1[0] + 0x57);
    }

    if (temp2[0] >= 0x00 && temp2[0] <= 0x09) {
    (data_out[j + 1]) = (byte) (temp2[0] + '0');
    } else if (temp2[0] >= 0x0a && temp2[0] <= 0x0f) {
    (data_out[j + 1]) = (byte) (temp2[0] + 0x57);
    }
    j += 2;
    }
    }

    /**
    * 将ASCII字符串转换成十六进制数据
    *
    * @param len
    * ASCII字符串长度
    * @param data_in
    * 待转换的ASCII字符串
    * @param data_out
    * 已转换的十六进制数据
    */
    private static void Ascii2Hex(int len, byte data_in[], byte data_out[]) {
    byte temp1[] = new byte[1];
    byte temp2[] = new byte[1];
    for (int i = 0, j = 0; i < len; j++) {
    temp1[0] = data_in[i];
    temp2[0] = data_in[i + 1];
    if (temp1[0] >= '0' && temp1[0] <= '9') {
    temp1[0] -= '0';
    temp1[0] = (byte) (temp1[0] << 4);

    temp1[0] = (byte) (temp1[0] & 0xf0);

    } else if (temp1[0] >= 'a' && temp1[0] <= 'f') {
    temp1[0] -= 0x57;
    temp1[0] = (byte) (temp1[0] << 4);
    temp1[0] = (byte) (temp1[0] & 0xf0);
    }

    if (temp2[0] >= '0' && temp2[0] <= '9') {
    temp2[0] -= '0';

    temp2[0] = (byte) (temp2[0] & 0x0f);

    } else if (temp2[0] >= 'a' && temp2[0] <= 'f') {
    temp2[0] -= 0x57;

    temp2[0] = (byte) (temp2[0] & 0x0f);
    }
    data_out[j] = (byte) (temp1[0] | temp2[0]);

    i += 2;
    }

    }

    protected String replaceAll(String strURL, String strAugs) {

    // JDK1.3中String类没有replaceAll的方法
    /** ********************************************************** */
    int start = 0;
    int end = 0;
    String temp = new String();
    while (start < strURL.length()) {
    end = strURL.indexOf(" ", start);
    if (end != -1) {
    temp = temp.concat(strURL.substring(start, end).concat("%20"));
    if ((start = end + 1) >= strURL.length()) {
    strURL = temp;
    break;
    }

    } else if (end == -1) {
    if (start == 0)
    break;
    if (start < strURL.length()) {
    temp = temp.concat(strURL.substring(start, strURL.length()));
    strURL = temp;
    break;
    }
    }

    }

    temp = "";
    start = end = 0;

    while (start < strAugs.length()) {
    end = strAugs.indexOf(" ", start);
    if (end != -1) {
    temp = temp.concat(strAugs.substring(start, end).concat("%20"));
    if ((start = end + 1) >= strAugs.length()) {
    strAugs = temp;
    break;
    }

    } else if (end == -1) {
    if (start == 0)
    break;
    if (start < strAugs.length()) {
    temp = temp.concat(strAugs.substring(start, strAugs.length()));
    strAugs = temp;
    break;
    }
    }

    }

    /** **************************************************************** */
    return strAugs;
    }
    }

  • 相关阅读:
    SpringBoot整合RabbitMq
    SpringBoot整合Mybatis
    Docker操作
    mysql高级复习
    mysql复习2
    springcloud复习2
    mysql复习1
    springcloud复习1
    JDBC(7)—DAO
    mysql报错:1130 -host 'localhost' is not allowed to connect to this mysql server
  • 原文地址:https://www.cnblogs.com/yangy608/p/2773206.html
Copyright © 2011-2022 走看看