java openssl 证书_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;

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值