java使用openssl生成的公钥和私钥进行签名

openssl的使用参考文章http://www.51know.info/system_base/openssl.html

主要是RSA和DSA的私钥和公钥生成,命令如下:

RSA生成1024位私钥:

 [root@hunterfu ~]# openssl genrsa -out private.key 1024
RSA生成公钥:

[root@hunterfu ~]# openssl rsa -in private.key -pubout -out pub.key
DSA生成私钥:

[root@hunterfu ~]# openssl dsaparam -out dsaparam.pem 1024
  [root@hunterfu ~]# openssl gendsa -out privkey.pem dsaparam.pem
DSA生成公钥:

[root@hunterfu ~]# openssl dsa -in privkey.pem -out pubkey.pem -pubout
  [root@hunterfu ~]# rm -fr dsaparam.pem

在删除dsaparam.pem文件前,可以通过-des / -des3 / -idea    对生成的私钥施加密码保护

  1. openssl gendsa -des3  -out privkey.pem dsaparam.pem  

特别注意的是,如果要通过java使用私钥,不论RSA还是DSA,必须通过PCKS#8转换:

[root@hunterfu ~]# openssl pkcs8 -topk8 -nocrypt -in private.key -outform PEM -out java_private.key
然后就可以使用网上常用的方法进行操作了:

package com.thfund.soa.message.security;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * @名称: Sign
 * @描述: 签名工具类,包括RSA和DSA签名验签方法 
 * @作者: 
 * @时间: 2014年7月15日
 * @版本: 1.0
 *
 */
public class Sign {
	
	public static String ALGORITHM_DSA="DSA";
	public static String ALGORITHM_RSA="RSA";
	
	public static byte[] base64Decoder(String data) throws IOException{
		BASE64Decoder base64Decoder = new BASE64Decoder();
		return base64Decoder.decodeBuffer(data);
	}
	
	public static String base64Encoder(byte[] data){
		BASE64Encoder base64Encoder=new BASE64Encoder();
		return base64Encoder.encodeBuffer(data);
	}


	
	/** 
	* @名称: readKeyFile 
	* @描述: 读取Key文件 
	* @param in
	* @return
	* @throws Exception
	* 
	*/
	public static String readKeyFile(InputStream in) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(in));
		String readLine = null;
		StringBuilder sb = new StringBuilder();
		while ((readLine = br.readLine()) != null) {
			if (readLine.charAt(0) == '-') {
				continue;
			} else {
				sb.append(readLine);
				sb.append('\r');
			}
		}
		return sb.toString(); 
	}
	
	public static PrivateKey loadPrivateKey(String privateKey,String algorithm) throws Exception{
		// 解密由base64编码的私钥   
        byte[] keyBytes = base64Decoder(privateKey);   
        // 构造PKCS8EncodedKeySpec对象   
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);   
        // KEY_ALGORITHM 指定的加密算法   
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);   
        // 取私钥匙对象   
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);   
        return priKey;
	}
	
	public static PublicKey loadPublicKey(String publicKey,String algorithm) throws Exception {
		byte[] buffer = base64Decoder(publicKey);
		KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
		PublicKey pubKey = keyFactory.generatePublic(keySpec);
		return pubKey;
	}

	/** 
	* @名称: rsaEncrypt 
	* @描述: RSA加密 
	* @param publicKey
	* @param plainTextData
	* @return
	* @throws Exception
	* 
	*/
	public static byte[] rsaEncrypt(RSAPublicKey publicKey, byte[] plainTextData)
			throws Exception {
		if (publicKey == null) {
			return null;
		}
		Cipher cipher = null;
		cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		byte[] output = cipher.doFinal(plainTextData);
		return output;
	}

	/** 
	* @名称: rsaDecrypt 
	* @描述: RSA解密 
	* @param privateKey
	* @param cipherData
	* @return
	* @throws Exception
	* 
	*/
	public static byte[] rsaDecrypt(RSAPrivateKey privateKey, byte[] cipherData)
			throws Exception {
		if (privateKey == null) {
			return null;
		}
		Cipher cipher = null;
		cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		byte[] output = cipher.doFinal(cipherData);
		return output;
	}

	/**
	 * @名称: genKeyPair
	 * @描述: 生成随机公钥私钥
	 * @return
	 * @throws Exception
	 * 
	 */
	public static Key[] genKeyPair() throws Exception {
		KeyPairGenerator keyPairGen = null;
		keyPairGen = KeyPairGenerator.getInstance("RSA");
		keyPairGen.initialize(1024);
		KeyPair keyPair = keyPairGen.generateKeyPair();
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
		Key[] key = new Key[2];
		key[0] = privateKey;
		key[1] = publicKey;
		return key;
	}
	
	
	
	public static String dsaSign(byte[] data,String privateKey) throws Exception{
		// 解密由base64编码的私钥   
        byte[] keyBytes = base64Decoder(privateKey);   
        // 构造PKCS8EncodedKeySpec对象   
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);   
        // KEY_ALGORITHM 指定的加密算法   
        KeyFactory keyFactory = KeyFactory.getInstance("DSA");   
        // 取私钥匙对象   
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);   
        // 用私钥对信息生成数字签名   
        Signature signature = Signature.getInstance(keyFactory.getAlgorithm());   
        signature.initSign(priKey);   
        signature.update(data);   
        return base64Encoder(signature.sign()); 
	}
	
	public static boolean dsaVerify(byte[] data, String publicKey, String sign) throws Exception{
		// 解密由base64编码的公钥   
        byte[] keyBytes = base64Decoder(publicKey);   
        // 构造X509EncodedKeySpec对象   
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);   
        // KEY_ALGORITHM 指定的加密算法   
        KeyFactory keyFactory = KeyFactory.getInstance("DSA");   
        // 取公钥匙对象   
        PublicKey pubKey = keyFactory.generatePublic(keySpec);   
        Signature signature = Signature.getInstance(keyFactory.getAlgorithm());   
        signature.initVerify(pubKey);   
        signature.update(data);   
        // 验证签名是否正常   
        return signature.verify(base64Decoder(sign));  
	}

	public static void main(String[] args) throws Exception{
		String str="这是一个测试字符串asdfdsafsaf123123测试";
		InputStream is=new FileInputStream("c:/rsa/pub.key");
    	byte[] bytes=rsaEncrypt((RSAPublicKey)loadPublicKey(readKeyFile(is),Sign.ALGORITHM_RSA),str.getBytes());
    	is.close();
    	System.out.println(new String(bytes));
    	is=new FileInputStream("c:/rsa/pkcs8_private.key"); 
    	bytes=Sign.rsaDecrypt((RSAPrivateKey)loadPrivateKey(readKeyFile(is),Sign.ALGORITHM_RSA), bytes);
    	System.out.println(new String(bytes));
    	is=new FileInputStream("c:/dsa/pkcs8_privkey.pem");
    	String sign=dsaSign(str.getBytes(),readKeyFile(is));
    	System.out.println(sign);
    	is=new FileInputStream("c:/dsa/pubkey.pem");
    	System.out.println(dsaVerify(str.getBytes(),readKeyFile(is),sign));
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值