JSON 接口如何實現 RSA 非對稱加密與簽名


代碼地址如下:
http://www.demodashi.com/demo/14000.html

一、概述

1、 數字簽名的作用:保證數據完整性,機密性和發送方角色的不可抵賴性,加密與簽字結合時,兩套公私鑰是不同的。

2、加密是對信息進行編碼和解碼的技術,編碼是把原來可讀信息(又稱明文)譯成代碼形式(又稱密文),其逆過程就是解碼(解密),加密技術的要點是加密算法,加密算法可以分為三類: .對稱加密 ,非對稱加密 ,不可逆加密。

3、對稱加密算法

a、加密過程: 將明文分成N個組,然后對各個組進行加密,形成各自的密文,最后把所有的分組密文進行合並,形成最終的密文。

b、優點: 算法公開、計算量小、加密速度快、加密效率高

c、缺點: 交易雙方都使用同樣鑰匙,安全性得不到保證,密鑰管理困難,尤其是在分布式網絡中

d、常用算法: DES、3DES(TripleDES)、AES、RC2、RC4、RC5和Blowfish

4、非對稱加密算法

a、使用過程: 乙方生成兩把密鑰(公鑰和私鑰),甲方獲取乙方的公鑰,然后用它對信息加密。乙方得到加密后的信息,用私鑰解密,乙方也可用私鑰加密字符串,甲方獲取乙方私鑰加密數據,用公鑰解密。

b、優點: 更安全,密鑰越長,它就越難破解

c、缺點: 加密速度慢

d、常用算法: RSA、Elgamal、背包算法、Rabin、D-H、ECC(橢圓曲線加密算法)

二、簽名詳細

簽名方法:

public static String sign(String content, String privateKey, String input_charset)
	{
        try 
        {
        	PKCS8EncodedKeySpec priPKCS8 	= new PKCS8EncodedKeySpec( Base64.decode(privateKey) ); 
        	KeyFactory keyf 				= KeyFactory.getInstance("RSA");
        	PrivateKey priKey 				= keyf.generatePrivate(priPKCS8);

            java.security.Signature signature = java.security.Signature
                .getInstance(SIGN_ALGORITHMS);

            signature.initSign(priKey);
            signature.update( content.getBytes(input_charset) );

            byte[] signed = signature.sign();
            
            return Base64.encode(signed);
        }
        catch (Exception e) 
        {
        	e.printStackTrace();
        }
        
        return null;
    }

驗證簽名方法

public static boolean verify(String content, String sign, String ali_public_key, String input_charset)
	{
		try 
		{
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
	        byte[] encodedKey = Base64.decode(ali_public_key);
	        PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

		
			java.security.Signature signature = java.security.Signature
			.getInstance(SIGN_ALGORITHMS);
		
			signature.initVerify(pubKey);
			signature.update( content.getBytes(input_charset) );
		
			boolean bverify = signature.verify( Base64.decode(sign) );
			return bverify;
			
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		
		return false;
	}

三、加密詳細

公鑰加密

public static byte[] encryptByPublicKey(byte[] data, String key)
			throws Exception
	{
		// 對公鑰解密
		byte[] keyBytes = decryptBASE64(key);
		// 取公鑰
		X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
		Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

		// 對數據解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		int length = data.length;
		byte[] enBytes = null;
		for (int i = 0; i < length; i += 64)
		{
			byte[] doFinal = cipher.doFinal(ArrayUtils
					.subarray(data, i, i + 64));
			enBytes = ArrayUtils.addAll(enBytes, doFinal);
		}
		return enBytes;
	}

私鑰解密

public static byte[] decryptByPrivateKey(byte[] data, String key)
			throws Exception
	{
		// 對私鑰解密
		byte[] keyBytes = decryptBASE64(key);

		PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
				keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
		Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
		// 對數據解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		byte[] deBytes = null;
		int length = data.length;
		for (int i = 0; i < length; i += 128)
		{
			byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i,
					i + 128));
			deBytes = ArrayUtils.addAll(deBytes, doFinal);
		}
		return deBytes;
	}

運行結果圖:

項目結構圖:

其他

如果使用了https,是否還需要對接口進行rsa加密或者簽名?
https 防止中間人攻擊, rsa驗證身份。 缺一不可。比如支付寶的訂單接口 https,誰都可以調用, 但是用你的rsa私鑰簽名是告訴支付寶:“這是我調用的”,當支付寶調用你的接口,通知你支付寶狀態的時候, 也會用它的私鑰簽名 告訴你“這的確是來着支付寶的請求”,這樣才能說明這個訂單 是真真實實成功的。

JSON 接口如何實現 RSA 非對稱加密與簽名

代碼地址如下:
http://www.demodashi.com/demo/14000.html

注:本文著作權歸作者,由demo大師代發,拒絕轉載,轉載需要作者授權


免責聲明!

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



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