參考文檔:
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(); } }