RSA生成、加密、解密、簽名。


首先,要會生成RSA密碼對。

https://app.alipay.com/market/document.htm?name=saomazhifu#page-23    (事例中的密鑰對好像有問題,最好用自己生成的。)

雖然說公鑰和私鑰都可以進行加密和解密,如果你是用公鑰加密,就需要用私鑰解密,如果你用的是私鑰加密,就需要用公鑰解密。

實際應用中,一般是自己保管私鑰,別人都用公鑰。所以,多數情況是公鑰加密,私鑰解密

import javax.crypto.Cipher;
import sun.security.rsa.RSAPublicKeyImpl;
import com.sun.org.apache.xml.internal.security.utils.Base64;


public class Main {

	public static String encrypt(String data, String publicKey){
		try{
			 byte[] keyBytes = Base64.decode(publicKey);
			 RSAPublicKeyImpl key = new RSAPublicKeyImpl(keyBytes);
			 Cipher cipher = Cipher.getInstance("RSA");
			 cipher.init(Cipher.ENCRYPT_MODE, key);   
			 byte[] encryptdata = cipher.doFinal(data.getBytes());   
			 return Base64.encode(encryptdata);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	public static void main(String[] args) {
		String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO2DT8szWj8TpQfwiaflBhZ6cBRRFm/vhkYm6mSpk5kMSU3RNvjQx+I0xoTz+r4y9JUMsbHYy9Undwq94Z9lgYHlJQMVDb4kkiyaAn1Veu9fiQ3wPwgwQC84V0ymuPnfhBt8KcaNtS0CAEtHvFwnBwx2vlMoaG+uGdxrJ3Pho4PwIDAQAB";
		System.out.println(encrypt("abc", publicKey));
		//其實這里隱藏了一個bug,加密出來的東西為了好看,它自動加了\n這樣的換行字符,
		//有些boss如果沒有把回車或是空白字符過濾掉的話,就會出錯。所以建議用 replayce一下。
		System.out.println(encrypt("abc", publicKey).replace("\n", ""));
		//細心的人就會發現,用同一個公鑰,加密同一個字符串的加密密文是不同的,說明這種加密算法比較強大,它會在里面自動的padding一些隨機信息。也就更安全。
		//當然了,用密鑰解出來就是一樣的了。
	}
}

我用的類基本上jdk都已集成,不用引用第三方包什么的,還是蠻方便的。

有時候會提示找不到RSAPublicKeyImpl類,這是jdk沒設置好的原因,右擊項目,選中properties,找到Java Build Path,然后在Libraries中

雙擊JRE System Library 然后選中Alternate JRE:定位到你安裝jdk的地方就ok了。

import java.security.Key;
import java.security.KeyFactory;
import javax.crypto.Cipher;
import java.security.spec.PKCS8EncodedKeySpec;
import com.sun.org.apache.xml.internal.security.utils.Base64;


public class Main2 {
	
	public static String decrypt(String data, String privateKey){
		try{
			 byte[] keyBytes = Base64.decode(privateKey);
			 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
			 KeyFactory keyFactory = KeyFactory.getInstance("RSA");   
			 Key privateKey2 = keyFactory.generatePrivate(pkcs8KeySpec);  
		
			 Cipher cipher = Cipher.getInstance("RSA");
			 cipher.init(Cipher.DECRYPT_MODE, privateKey2);   
			 byte[] encryptdata = cipher.doFinal(Base64.decode(data));   
			 return new String(encryptdata);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	public static void main(String[] args) {
		String data = "EEzWXpVZ6FPJOzQASGDfZuCg7nLsyT2fwF85qwD5OXoCwtxCPkej+PkRDOispR0m327cEc7clm6Wqg4bXMxfehc7bkILtSsTIeNkAQMzoB7/xpMeGi6oQFQJJ1PvLqMTb4s+lhKvoBhER8XM/PXIGanL+trDeLcPG7NR72qu4TI=";
		String privateKey = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAM7YNPyzNaPxOlB/CJp+UGFnpwFFEWb++GRibqZKmTmQxJTdE2+NDH4jTGhPP6vjL0lQyxsdjL1Sd3Cr3hn2WBgeUlAxUNviSSLJoCfVV671+JDfA/CDBALzhXTKa4+d+EG3wpxo21LQIAS0e8XCcHDHa+Uyhob64Z3Gsnc+Gjg/AgMBAAECgYAb/exlykbXEd0naZmbdr6f/+v84wDw5E5vH1cEEBJeVPYVgzmPHhJzu4kqkJb4Rv1uOY3S9JPIRzG8wLWE4+6VzpF89/oR4O7rb8FV5Ma1I0oXNWyTy5wxqSt39bZZK/12vA58iomt7/+D3k1Z1V55XBNKI0s3SoXkD3pfECAQkQJBAPXV3uh4VOt3kX5GYxs0amF/DxWGFhLvsQWNKNXHK/47r4owVLCw/JDhelfMnWP/AmmANTgO1jnE/GW/RayPN3cCQQDXZZ++PKmhYqFaOPWmO5MItKo9iI5CPiMSZK3yF9nQjqBkquJnbL2XcP/nZqy//xs4lHs52A1qzS2e/xH58Ud5AkEAsUyYQY1XoaNQmYPmQl6hQsPCe0GDdhDM2TYfd174SZl+VunYir56yXr1I5F9CfuHH9PJji6VLoD1j+RNOdDorQJBAMxIEk9u4wYvL44M1VUZzSIFjiubtie3HLYWDC69VhOJIS84Lk8ef1UAk4MYCqBwxpVLpO7ALEFtZGYVzSu6HCkCQQDADWjpnSTo2l5yqYaA8nz4puKAbETC9F3RwMbwHlCY/HZ1QN077E2/3vAI4m0C1ssjN+reszqHUZihBwA5Eg/w";
		System.out.println(decrypt(data, privateKey));
	}
}

簽名與驗證

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import com.sun.org.apache.xml.internal.security.utils.Base64;


public class Main3 {
	
	public static String sign(String data, String privateKey){
		try{
	        byte[] keyBytes = Base64.decode(privateKey);
	        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
	        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
	        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
	        
	        Signature signature = Signature.getInstance("MD5withRSA");
	        signature.initSign(privateK);
	        signature.update(data.getBytes());
	        return Base64.encode(signature.sign());
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
    public static boolean verify(String data, String publicKey, String sign){
    	try{
            byte[] keyBytes = Base64.decode(publicKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicK = keyFactory.generatePublic(keySpec);
            Signature signature = Signature.getInstance("MD5withRSA");
            signature.initVerify(publicK);
            signature.update(data.getBytes());
            return signature.verify(Base64.decode(sign));
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    	return false;
    }
	
	public static void main(String[] args) {
		String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO2DT8szWj8TpQfwiaflBhZ6cBRRFm/vhkYm6mSpk5kMSU3RNvjQx+I0xoTz+r4y9JUMsbHYy9Undwq94Z9lgYHlJQMVDb4kkiyaAn1Veu9fiQ3wPwgwQC84V0ymuPnfhBt8KcaNtS0CAEtHvFwnBwx2vlMoaG+uGdxrJ3Pho4PwIDAQAB";
		String privateKey = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAM7YNPyzNaPxOlB/CJp+UGFnpwFFEWb++GRibqZKmTmQxJTdE2+NDH4jTGhPP6vjL0lQyxsdjL1Sd3Cr3hn2WBgeUlAxUNviSSLJoCfVV671+JDfA/CDBALzhXTKa4+d+EG3wpxo21LQIAS0e8XCcHDHa+Uyhob64Z3Gsnc+Gjg/AgMBAAECgYAb/exlykbXEd0naZmbdr6f/+v84wDw5E5vH1cEEBJeVPYVgzmPHhJzu4kqkJb4Rv1uOY3S9JPIRzG8wLWE4+6VzpF89/oR4O7rb8FV5Ma1I0oXNWyTy5wxqSt39bZZK/12vA58iomt7/+D3k1Z1V55XBNKI0s3SoXkD3pfECAQkQJBAPXV3uh4VOt3kX5GYxs0amF/DxWGFhLvsQWNKNXHK/47r4owVLCw/JDhelfMnWP/AmmANTgO1jnE/GW/RayPN3cCQQDXZZ++PKmhYqFaOPWmO5MItKo9iI5CPiMSZK3yF9nQjqBkquJnbL2XcP/nZqy//xs4lHs52A1qzS2e/xH58Ud5AkEAsUyYQY1XoaNQmYPmQl6hQsPCe0GDdhDM2TYfd174SZl+VunYir56yXr1I5F9CfuHH9PJji6VLoD1j+RNOdDorQJBAMxIEk9u4wYvL44M1VUZzSIFjiubtie3HLYWDC69VhOJIS84Lk8ef1UAk4MYCqBwxpVLpO7ALEFtZGYVzSu6HCkCQQDADWjpnSTo2l5yqYaA8nz4puKAbETC9F3RwMbwHlCY/HZ1QN077E2/3vAI4m0C1ssjN+reszqHUZihBwA5Eg/w";
		String sign = sign("abc", privateKey);
		System.out.println(verify("abc", publicKey , sign));
	}
}

最近補充一下js版的RSA加解密和簽名:加密解最好用的是jsencrypt.js ,簽名最好用的是jsrsasign.js 。曾經我也用痛苦地用過RSA.js ,但是它很難用,首先是它的參數對我是一種考驗,一開始都不知道那些參數怎么填,才來才慢慢明白,還有就是RSA.js加密是沒有padding的,它每次加密出來的東西只要公鑰和數據一樣,加密出來就是一樣的密文,這個還必須得用  bcprov-jdk15-143.jar

			 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());  
			 final Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC");  

這個來解,但是一般的boss系統都不這么干,所以RSA.js並不好用,果斷放棄吧。

代碼如下:

function encrypt(data){  //加密
    var _encrypt = new JSEncrypt();
    _encrypt.setPublicKey(boss_public_key);
    var encrypted = _encrypt.encrypt(data);
    return encrypted;
}

function decrypt(data){
    var _decrypt = new JSEncrypt();
    _decrypt.setPrivateKey(Merchant_private_key);
    var uncrypted = _decrypt.decrypt(data);
    return uncrypted;
}

function sign(data){  //簽名
  var rsa = KEYUTIL.getRSAKeyFromPlainPKCS8PEM("-----BEGIN PRIVATE KEY-----" + Merchant_private_key + "-----END PRIVATE KEY-----");
  var result = rsa.signString(data, "md5");
  return base64_encode(code_conversion(result));
}

 這里是用到的幾個js  http://pan.baidu.com/s/1mg5ub3M

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM