参考文档:
http://blog.csdn.net/chaijunkun/article/details/7275632
生成私钥
openssl genrsa -out rsa_private_key.pem 1024
用私钥产生公钥
openssl rsa -in rsa_private_key.pem -out public_key.pem -pubout
私钥加工(PKCS#8编码)
openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt
将public_key.pem给需要加密的一端。
将pkcs8_rsa_private_key.pem给需要解密的一端。
私钥端签名,公钥端验证签名
公钥端加密,私钥端解密。
来自百度:
第一种是签名,使用私钥加密,公钥解密,用于让所有公钥所有者验证私钥所有者的身份并且用来防止私钥所有者发布的内容被篡改.但是不用来保证内容不被他人获得.
第二种是加密,用公钥加密,私钥解密,用于向公钥所有者发布信息,这个信息可能被他人篡改,但是无法被他人获得.
如果甲想给乙发一个安全的保密的数据,那么应该甲乙各自有一个私钥,甲先用乙的公钥加密这段数据,再用自己的私钥加密这段加密后的数据.最后再发给乙,这样确保了内容即不会被读取,也不会被篡改.
举例(java)
public class CodecUtils { static String private_pem_file = "/pkcs8_rsa_private_key.pem"; static String public_pem_file = "/public_key.pem"; private static String getKey(String filename) throws IOException { // Read key from file String strKeyPEM = ""; BufferedReader br = new BufferedReader(new InputStreamReader(CodecUtils.class.getResourceAsStream(filename))); String line; while ((line = br.readLine()) != null) { strKeyPEM += line + "\n"; } br.close(); return strKeyPEM; } public static RSAPrivateKey getPrivateKey() throws IOException, GeneralSecurityException{ return getPrivateKey(private_pem_file); } public static RSAPrivateKey getPrivateKey(String filename) throws IOException, GeneralSecurityException { String privateKeyPEM = getKey(filename); return getPrivateKeyFromString(privateKeyPEM); } public static RSAPrivateKey getPrivateKeyFromString(String key) throws IOException, GeneralSecurityException { String privateKeyPEM = key; privateKeyPEM = privateKeyPEM.replace("-----BEGIN PRIVATE KEY-----\n",""); privateKeyPEM = privateKeyPEM.replace("-----END PRIVATE KEY-----", ""); byte[] encoded = Base64.decodeBase64(privateKeyPEM); KeyFactory kf = KeyFactory.getInstance("RSA"); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(keySpec); return privKey; } public static RSAPublicKey getPublicKey() throws IOException, GeneralSecurityException{ return getPublicKey(public_pem_file); } public static RSAPublicKey getPublicKey(String filename) throws IOException, GeneralSecurityException { String publicKeyPEM = getKey(filename); return getPublicKeyFromString(publicKeyPEM); } public static RSAPublicKey getPublicKeyFromString(String key) throws IOException, GeneralSecurityException { String publicKeyPEM = key; publicKeyPEM = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----\n", ""); publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", ""); byte[] encoded = Base64.decodeBase64(publicKeyPEM); KeyFactory kf = KeyFactory.getInstance("RSA"); RSAPublicKey pubKey = (RSAPublicKey) kf .generatePublic(new X509EncodedKeySpec(encoded)); return pubKey; } public static String sign(PrivateKey privateKey, String message) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, UnsupportedEncodingException { Signature sign = Signature.getInstance("SHA1withRSA"); sign.initSign(privateKey); sign.update(message.getBytes("UTF-8")); return new String(Base64.encodeBase64(sign.sign()), "UTF-8"); } public static boolean verify(PublicKey publicKey, String message, String signature) throws SignatureException, NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException { Signature sign = Signature.getInstance("SHA1withRSA"); sign.initVerify(publicKey); sign.update(message.getBytes("UTF-8")); return sign.verify(Base64.decodeBase64(signature.getBytes("UTF-8"))); } public static String encrypt(String rawText, PublicKey publicKey) throws IOException, GeneralSecurityException { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return Base64.encodeBase64String(cipher.doFinal(rawText .getBytes("UTF-8"))); } public static String decrypt(String cipherText, PrivateKey privateKey) throws IOException, GeneralSecurityException { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); return new String(cipher.doFinal(Base64.decodeBase64(cipherText)), "UTF-8"); } }
测试
public void testSSL() { //encode,Data must not be longer than 117 bytes String data = "hello world "; try { RSAPrivateKey privateKey = CodecUtils.getPrivateKey(); RSAPublicKey publicKey = CodecUtils.getPublicKey(); String encodeStr = CodecUtils.encrypt(data, publicKey); String decodeStr = CodecUtils.decrypt(encodeStr, privateKey); System.out.println("endode str:"); System.out.println(encodeStr + " / " + encodeStr.length()); System.out.println("after decode:"); System.out.println(decodeStr); String signStr = CodecUtils.sign(privateKey, data); System.out.println("signature:"); System.out.println(signStr+ " / " + signStr.length()); System.out.println("verify signature:"); System.out.println(CodecUtils.verify(publicKey, data, signStr)); } catch (IOException | GeneralSecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } }