如下是php封裝好的類,引入便可使用php
<?php /** * 做者:pjp * 郵箱:vippjp@163.com */ class RSA{ private $privateKey='';//私鑰(用於用戶加密) private $publicKey='';//公鑰(用於服務端數據解密) public function __construct(){ $this->privateKey = openssl_pkey_get_private(file_get_contents('php_private.pem'));//私鑰,用於加密 $this->publicKey = openssl_pkey_get_public(file_get_contents('php_public.pem'));//公鑰,用於解密 } /** * 私鑰加密 * @param 原始數據 $data * @return 密文結果 string */ public function encryptByPrivateKey($data) { openssl_private_encrypt($data,$encrypted,$this->privateKey,OPENSSL_PKCS1_PADDING);//私鑰加密 $encrypted = base64_encode($encrypted);//加密後的內容一般含有特殊字符,須要編碼轉換下,在網絡間經過url傳輸時要注意base64編碼是不是url安全的 return $encrypted; } /** * 私鑰解密 * @param 密文數據 $data * @return 原文數據結果 string */ public function decryptByPrivateKey($data){ $data = base64_decode($data); openssl_private_decrypt($data,$encrypted,$this->privateKey,OPENSSL_PKCS1_PADDING);//私鑰解密 return $encrypted; } /** * 私鑰簽名 * @param unknown $data */ public function signByPrivateKey($data){ openssl_sign($data, $signature, $this->privateKey); $encrypted = base64_encode($signature);//加密後的內容一般含有特殊字符,須要編碼轉換下,在網絡間經過url傳輸時要注意base64編碼是不是url安全的 return $encrypted; } /** * 公鑰加密 * @param 原文數據 $data * @return 加密結果 string */ public function encryptByPublicKey($data) { openssl_public_encrypt($data,$decrypted,$this->publicKey,OPENSSL_PKCS1_PADDING);//公鑰加密 return base64_encode($decrypted); } /** * 公鑰解密 * @param 密文數據 $data * @return 原文結果 string */ public function decryptByPublicKey($data) { $data = base64_decode($data); openssl_public_decrypt($data,$decrypted,$this->publicKey,OPENSSL_PKCS1_PADDING);//公鑰解密 return $decrypted; } /** * 公鑰驗籤 * @param unknown $data * @param unknown $sign */ public function verifyByPublicKey($data,$sign){ $sign = base64_decode($sign); return openssl_verify($data, $sign, $this->publicKey); } public function __destruct(){ openssl_free_key($this->privateKey); openssl_free_key($this->publicKey); } } ?>
php公鑰文件內容(php_public.pem)java
公鑰和私鑰皆可本身從新生成算法
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCm1YchJdHVy9iXsDfQfMEB2mdO 5wuaEiqUEerHO7HbKKkvhuIfc7haQV5bKTiKZ76FnkkXJMF+onMrQrrqk4TiWlYZ oilesPM88jr01Z9MmhzKV7vWboVhYcd8cw2Mua0HwAMyl9TDt5OLWmT00C4/Lu72 lRL21avxRTvmDQoAqQIDAQAB -----END PUBLIC KEY-----
php私鑰文件內容(php_private.pem)安全
-----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKbVhyEl0dXL2Jew N9B8wQHaZ07nC5oSKpQR6sc7sdsoqS+G4h9zuFpBXlspOIpnvoWeSRckwX6icytC uuqThOJaVhmiKV6w8zzyOvTVn0yaHMpXu9ZuhWFhx3xzDYy5rQfAAzKX1MO3k4ta ZPTQLj8u7vaVEvbVq/FFO+YNCgCpAgMBAAECgYB1x4s1eJiyAc4wEITm2Bv+Lez/ BBfptmd+z0NbUiZW3VbLqcLbh3ufpERzwR8cfu8/L6bUAuvjddYutVZ2Ip0Nd7dG 5rrktH+7R8UT89fn87bUa5NlLee+egyoz/PJ63X4JjEg5OJbkXMbK4YrTypS0IAx nZv+7BeSsCrzNlpWAQJBANgmHMDNrIWvU3qVf7u8SS/g+WrlvKMWOXtYjH2OqWoO Vtmh4Or1PbaPIMnPAXFYiYYW8wcLYnVmVCez5qaysWkCQQDFl9XONZIMFAvdJ5S2 UFk63bEYtCroKZjddTlE6K/j+Vj2IaCFm94i4x1YzJR0KrykrtBTLRi7nuWmdJMJ r61BAkA7dxDGAk+KX9fJi8OedIh2AaDcxeOFwqGBy7Sq/kqhgNxn918XhOy7gtj0 bFzrP/5lw36M25b00XgpjBbSmaqxAkBnBN/TUHjh1T3OQ0m0uDWdjGI+KAlK3A04 QVrng43ZBXMNeMDRiE+Lzu/JEXjBDFsoXYB+LT/86j5/x721yiNBAkEAgi0F5BvA wYZQXqAx3iyuj8R9uUKpLePafyBRHnLNrFux2VD0ZX3pXCmfDDmtM/NMO491dI84 6NbVOvxWcNPQ/Q== -----END PRIVATE KEY-----
如下是java封裝好的方法服務器
/** * 做者:pjp * 郵箱:vippjp@163.com */ package crypt; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.security.KeyFactory; 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; public class Rsa { private String priKey; private String pubKey; public static void main(String[] args) { Rsa rsa = new Rsa(); String str = "我要加密這段文字。"; System.out.println("原文:"+"我要加密這段文字。"); String crypt = rsa.encryptByPrivateKey(str); System.out.println("私鑰加密密文:"+crypt); String result = rsa.decryptByPublicKey(crypt); System.out.println("原文:"+result); System.out.println("---"); str = "我要加密這段文字。"; System.out.println("原文:"+"我要加密這段文字。"); crypt = rsa.encryptByPublicKey(str); System.out.println("公鑰加密密文:"+crypt); result = rsa.decryptByPrivateKey(crypt); System.out.println("原文:"+result); System.out.println("---"); str = "我要簽名這段文字。"; System.out.println("原文:"+str); String str1 = rsa.signByPrivateKey(str); System.out.println("簽名結果:"+str1); if(rsa.verifyByPublicKey(str1, str)){ System.out.println("成功"); } else { System.out.println("失敗"); } } public Rsa(){ priKey = readStringFromFile("java_private.pem"); pubKey = readStringFromFile("java_public.pem"); } /** * 使用私鑰加密 * @see decByPriKey */ public String encryptByPrivateKey(String data) { // 加密 String str = ""; try { byte[] pribyte = base64decode(priKey.trim()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec); Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); c1.init(Cipher.ENCRYPT_MODE, privateKey); str = base64encode(c1.doFinal(data.getBytes())); } catch (Exception e) { e.printStackTrace(); } return str; } /** * 使用私鑰解密 * @see decByPriKey */ public String decryptByPrivateKey(String data) { // 加密 String str = ""; try { byte[] pribyte = base64decode(priKey.trim()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec); Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); c1.init(Cipher.DECRYPT_MODE, privateKey); byte[] temp = c1.doFinal(base64decode(data)); str = new String(temp); } catch (Exception e) { e.printStackTrace(); } return str; } /** * 使用公鑰加密 * @see decByPriKey */ public String encryptByPublicKey(String data) { // 加密 String str = ""; try { byte[] pubbyte = base64decode(pubKey.trim()); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec); Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); c1.init(Cipher.ENCRYPT_MODE, rsaPubKey); str = base64encode(c1.doFinal(data.getBytes())); } catch (Exception e) { e.printStackTrace(); } return str; } /** * 使用公鑰解密 * @see decByPriKey */ public String decryptByPublicKey(String data) { // 加密 String str = ""; try { byte[] pubbyte = base64decode(pubKey.trim()); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec); Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); c1.init(Cipher.DECRYPT_MODE, rsaPubKey); byte[] temp = c1.doFinal(base64decode(data)); str = new String(temp); } catch (Exception e) { e.printStackTrace(); } return str; } /** * 本方法使用SHA1withRSA簽名算法產生簽名 * @param String src 簽名的原字符串 * @return String 簽名的返回結果(16進制編碼)。當產生簽名出錯的時候,返回null。 */ public String signByPrivateKey(String src) { try { Signature sigEng = Signature.getInstance("SHA1withRSA"); byte[] pribyte = base64decode(priKey.trim()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec); sigEng.initSign(privateKey); sigEng.update(src.getBytes()); byte[] signature = sigEng.sign(); return base64encode(signature); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 使用共鑰驗證簽名 * @param sign * @param src * @return */ public boolean verifyByPublicKey(String sign, String src) { try { Signature sigEng = Signature.getInstance("SHA1withRSA"); byte[] pubbyte = base64decode(pubKey.trim()); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec); sigEng.initVerify(rsaPubKey); sigEng.update(src.getBytes()); byte[] sign1 = base64decode(sign); return sigEng.verify(sign1); } catch (Exception e) { e.printStackTrace(); return false; } } /** * base64加密 * @param bstr * @return */ @SuppressWarnings("restriction") private String base64encode(byte[] bstr) { String str = new sun.misc.BASE64Encoder().encode(bstr); str = str.replaceAll("\r\n", "").replaceAll("\r", "").replaceAll("\n", ""); return str; } /** * base64解密 * @param str * @return byte[] */ @SuppressWarnings("restriction") private byte[] base64decode(String str) { byte[] bt = null; try { sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder(); bt = decoder.decodeBuffer(str); } catch (IOException e) { e.printStackTrace(); } return bt; } /** * 從文件中讀取全部字符串 * @param fileName * @return String */ private String readStringFromFile(String fileName){ StringBuffer str = new StringBuffer(); try { File file = new File(fileName); FileReader fr = new FileReader(file); char[] temp = new char[1024]; while (fr.read(temp) != -1) { str.append(temp); } fr.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return str.toString(); } }
java公鑰文件內容(java_public.pem)網絡
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCm1YchJdHVy9iXsDfQfMEB2mdO 5wuaEiqUEerHO7HbKKkvhuIfc7haQV5bKTiKZ76FnkkXJMF+onMrQrrqk4TiWlYZ oilesPM88jr01Z9MmhzKV7vWboVhYcd8cw2Mua0HwAMyl9TDt5OLWmT00C4/Lu72 lRL21avxRTvmDQoAqQIDAQAB
java私鑰文件內容(java_private.pem)app
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKbVhyEl0dXL2Jew N9B8wQHaZ07nC5oSKpQR6sc7sdsoqS+G4h9zuFpBXlspOIpnvoWeSRckwX6icytC uuqThOJaVhmiKV6w8zzyOvTVn0yaHMpXu9ZuhWFhx3xzDYy5rQfAAzKX1MO3k4ta ZPTQLj8u7vaVEvbVq/FFO+YNCgCpAgMBAAECgYB1x4s1eJiyAc4wEITm2Bv+Lez/ BBfptmd+z0NbUiZW3VbLqcLbh3ufpERzwR8cfu8/L6bUAuvjddYutVZ2Ip0Nd7dG 5rrktH+7R8UT89fn87bUa5NlLee+egyoz/PJ63X4JjEg5OJbkXMbK4YrTypS0IAx nZv+7BeSsCrzNlpWAQJBANgmHMDNrIWvU3qVf7u8SS/g+WrlvKMWOXtYjH2OqWoO Vtmh4Or1PbaPIMnPAXFYiYYW8wcLYnVmVCez5qaysWkCQQDFl9XONZIMFAvdJ5S2 UFk63bEYtCroKZjddTlE6K/j+Vj2IaCFm94i4x1YzJR0KrykrtBTLRi7nuWmdJMJ r61BAkA7dxDGAk+KX9fJi8OedIh2AaDcxeOFwqGBy7Sq/kqhgNxn918XhOy7gtj0 bFzrP/5lw36M25b00XgpjBbSmaqxAkBnBN/TUHjh1T3OQ0m0uDWdjGI+KAlK3A04 QVrng43ZBXMNeMDRiE+Lzu/JEXjBDFsoXYB+LT/86j5/x721yiNBAkEAgi0F5BvA wYZQXqAx3iyuj8R9uUKpLePafyBRHnLNrFux2VD0ZX3pXCmfDDmtM/NMO491dI84 6NbVOvxWcNPQ/Q==
說明:測試
java和php的RSA加解密版本已所有經過測試。而且能夠相互加解密。
私鑰是服務器保留,公鑰能夠發放給對應的客戶端,甚至能夠是公共的。
採用私鑰加密-》公鑰解密 和 公鑰加密-》私鑰解密 的加密方式。
可是若是客戶端是須要更高安全性的支付系統,那麼應該採用兩對密鑰。
每一方分別是本身的私鑰和對方的公鑰,採用私鑰加密並簽名-》公鑰解密並驗籤的方式。this
注意:給出的是兩個版本的兩對密鑰,實際上只是一對密鑰。區別是java的密鑰去掉了頭尾註釋。而PHP的密鑰保留了頭尾註釋。編碼
from:https://blog.csdn.net/panjiapengfly/article/details/75318930