1. 程式人生 > >php和java之間rsa加密互通

php和java之間rsa加密互通

以下是php封裝好的類,引入即可使用

<?php
/**
 * 作者:pjp
 * 郵箱:[email protected]
 */
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)

公鑰和私鑰皆可自己重新生成

-----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
 * 郵箱:[email protected]
 */
 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)

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加解密版本已全部通過測試。並且可以相互加解密。
私鑰是伺服器保留,公鑰可以發放給對應的客戶端,甚至可以是公共的。
採用私鑰加密-》公鑰解密 和 公鑰加密-》私鑰解密 的加密方式。
但是如果客戶端是需要更高安全性的支付系統,那麼應該採用兩對金鑰。
每一方分別是自己的私鑰和對方的公鑰,採用私鑰加密並簽名-》公鑰解密並驗籤的方式。

注意:給出的是兩個版本的兩對金鑰,實際上只是一對金鑰。區別是java的金鑰去掉了頭尾註釋。而PHP的金鑰保留了頭尾註釋。

相關推薦

phpjava之間rsa加密互通

以下是php封裝好的類,引入即可使用 <?php /** * 作者:pjp * 郵箱:[email protected] */ class RSA{ private $privateKey='';//私鑰(用於使用者加密) private $pu

phpjava之間aes加密互通

<?php class Security { public static function encrypt($input, $key) { $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MOD

phpjava中的加密解密

padding 而不是 bsp enc openss 解密 div des算法 -c 遇到的java代碼如下: Cipher cipher=Cipher.getInstance("DESede/CBC/PKCS5Padding"); 在php中使用des算法 始終校驗不

iOSjava之間RSA加密解密、加簽認證對接

對接場景: 伺服器端使用java生成公鑰和私鑰,將公鑰傳遞給iOS加密 or 將私鑰傳遞給iOS端使用openssl進行簽名,然後在伺服器端進行驗證 java端: 1、使用常規的KeyPairGenerator類生成公鑰和私鑰 KeyPairGenerator gen =

C# 與JAVARSA 加密解密交互,互通,C#使用BouncyCastle來實現私鑰加密,公鑰解密的方法

cipher process [] var class mar tor als get 因為C#的RSA加密解密只有公鑰加密,私鑰解密,沒有私鑰加密,公鑰解密。在網上查了很久也沒有很好的實現。BouncyCastle的文檔少之又少。很多人可能會說,C#也是可以的,通過Big

php js之間使用json通信

鍵值 type 依然 字符 從數據 信息 轉換成 數據轉換 行處理   有時候我們需要用後臺從數據庫中得到的數據在js中進行處理,但是當從php中獲取到數據的時候,使用的是鍵值對形式的多維關聯數組。而我們知道,js只支持索引數組,不支持關聯數組,這個時候從後臺傳遞過來的數據

Java使用RSA加密算法對內容進行加密

hat trac ogg size gen cte false static doc 什麽是RSA加密算法 RSA是一種典型的非對稱性加密算法,具體介紹可參考阮一峰的日誌 RSA算法原理 下面是使用RSA算法對傳輸內容進行加密的一個簡要Java案例,主要用到了三個類,大體實

我來談談PHPJAVA在web開發上的的區別

高性能 分鐘 turn 小時 gpo 處理 body 功能 而且 這裏的標題寫的是談談PHP和JAVA的區別,其實是委婉的說法,其實別人是想聽PHP好還是JAVA好!!! 從而從中找到存在感!!!   因為由於我是從多年的php開發轉到java開發的。所以最,不時的有好幾

寶塔phpjava項目同時使用80端口nginx配置

set add ive HP ati real keepaliv stream 配置 upstream nhpay_cookingeasy_cn { server 39.105.134.128:8080; keepalive 2000;} server {

phpJava哪個好?phpJava的對比

php和Java哪個好?這個問題應該會有很多人問,但是每種程式語言都有各自的優缺點,所謂的哪個好,不過就是看你習慣於使用哪種或者說你更擅長於哪種,所以今天我們就來說一說php和Java之間的對比。   1、php與Java的語法比較 php是解釋執行的伺服器指令碼語言,首先ph

條理清晰的入門:使用Java實現RSA加密解密

條理清晰的入門:使用Java實現RSA加密解密 什麼是RSA 使用Java 需要匯入的標頭檔案 生成公鑰、私鑰 進行加密解密 金鑰的儲存 密文的儲存、讀取 什麼是RSA 翻一下以前的密碼

C#java之間的一些差異與共性

C#與java之間的一些共性和差異整理隱藏:與java中的重寫幾乎一致,但是需要新增new關鍵字讓編譯器知道,否則會有警告虛方法:1.宣告為virtual的方法就是虛方法,在子類中使用override進行重寫,當程式發現該方法是虛方法時,會去尋找子類中是否重寫了該方法,如果被

JAVA利用RSA加密演算法的長度限制問題解決完整程式碼

package com.additional; import java.io.ByteArrayOutputStream;   import java.security.Key;   import java.security.KeyFactory;   import jav

JAVA實現RSA加密解密

RSA 工具類。提供加密,解密,生成金鑰對等方法。  RSA加密原理概述   : RSA的安全性依賴於大數的分解,公鑰和私鑰都是兩個大素數(大於100的十進位制位)的函式。 據猜測,從一個金鑰和密文推斷出明文的難度等同於分解兩個大素數的積    金鑰的產生:     1.選

JAVA實現RSA加密,非對稱加密演算法

RSA.java package org.icesnow.jeasywx.util.security; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair;

Java使用RSA加密解密簽名及校驗

由於專案要用到非對稱加密解密簽名校驗什麼的,於是參考《Java加密解密的藝術》寫一個RSA進行加密解密簽名及校驗的Demo,程式碼很簡單,特此分享!RSA加密解密類:package com.ihep; import java.io.BufferedReader; impor

jsjava之間的中文Base64轉碼

中文js和java之間的Base64轉碼 使用現有的js和Java包 1、js 使用jquery.base64.js進行編碼。 下載連結: 2、java使用Base64.decodeBase64進行解碼。 //maven <dependency>

javaRSA加密

 package com.jetsum.util; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWr

Java 實現 RSA加密解密及數字簽名

RSA公鑰加密演算法是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。當時他們三人都在麻省理工學院工作。RSA就是他們三人姓氏開頭字母拼在一起組成的。 RSA是目

PHPJava AES 128 ECB 加解密(PKCS5Padding)

php 和 java 使用 AES128/ECB/PKCS5Padding對稱加解密,簽名使用 HmacSHA256,附帶 php 和 java 程式碼,均為 DEMO 版本,測試通過,實際使用請根據自己專案修改。 最近做專案涉及到一丟丟的安全問題,需