openssl的使用参考文章http://www.51know.info/system_base/openssl.html
主要是RSA和DSA的私钥和公钥生成,命令如下:
RSA生成1024位私钥:
[root@hunterfu ~]# openssl genrsa -out private.key 1024RSA生成公钥:
[root@hunterfu ~]# openssl rsa -in private.key -pubout -out pub.keyDSA生成私钥:
[root@hunterfu ~]# openssl dsaparam -out dsaparam.pem 1024 [root@hunterfu ~]# openssl gendsa -out privkey.pem dsaparam.pemDSA生成公钥:
[root@hunterfu ~]# openssl dsa -in privkey.pem -out pubkey.pem -pubout [root@hunterfu ~]# rm -fr dsaparam.pem
在删除dsaparam.pem文件前,可以通过-des / -des3 / -idea 对生成的私钥施加密码保护
- 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));
}
}