Android加密算法

Android加密算法

各種加密算法詳解:http://www.cnblogs.com/whoislcj/category/830987.html


基本需求及概念

隨着Internet網的廣泛應用,信息安全問題日益突出,以數據加密技術爲核心的信息安全技術也得到了極大的發展。目前的數據加密技術根據加密密鑰類型可分私鑰加密(對稱加密)系統和公鑰加密(非對稱加密)系統。

對稱加密算法是較傳統的加密體制,通信雙方在加/解密過程中使用他們共享的單一密鑰,鑑於其算法簡單和加密速度快的優點,目前仍然是主流的密碼體制之一。最常用的對稱密碼算法是數據加密標準(DES)算法,但是由於DES密鑰長度較短,已經不適合當今分佈式開放網絡對數據加密安全性的要求。最後,一種新的基於Rijndael算法對稱高級數據加密標準AES取代了數據加密標準DES。非對稱加密由於加/解密鑰不同(公鑰加密,私鑰解密),密鑰管理簡單,也得到廣泛應用。RSA是非對稱加密系統最著名的公鑰密碼算法

AES算法

美國國家標準和技術研究所(NIST)經過三輪候選算法篩選,從衆多的分組密碼中選中Rijndael算法作爲高級加密標準(AES)。Rijndael密碼是一個迭代型分組密碼,分組長度和密碼長度都是可變的,分組長度和密碼長度可以獨立的指定爲128比特,192比特或者256比特。AES的加密算法的數據處理單位是字節,128位的比特信息被分成16個字節,按順序複製到一個4*4的矩陣中,稱爲狀態(state),AES的所有變換都是基於狀態矩陣的變換。

用Nr表示對一個數據分組加密的輪數(加密輪數與密鑰長度的關係如表1所示)。在輪函數的每一輪迭代中,包括四步變換,分別是字節代換運算(ByteSub())、行變換(ShiftRows())、列混合(MixColumns())以及輪密鑰的添加變換AddRoundKey()[3],其作用就是通過重複簡單的非線形變換、混合函數變換,將字節代換運算產生的非線性擴散,達到充分的混合,在每輪迭代中引入不同的密鑰,從而實現加密的有效性。

下面是三種不同類型的AES加密密鑰分組大小與相應的加密輪數的對照表。加密開始時,輸入分組的各字節按表2 的方式裝入矩陣state中。如輸入ABCDEFGHIJKLMNOP,則輸入塊影射到如表2的狀態矩陣中。
表1:

AES類型 密鑰長度 分組長度 加密輪數
AES-128 4字 4字 10
AES-192 6字 4字 12
AES-256 8字 4字 14

A E I M
B F J N
C G K O
D H L P

1、字節代換運算(ByteSub())

字節代換運算是一個可逆的非線形字節代換操作,對分組中的每個字節進行,對字節的操作遵循一個代換表,即S盒。S盒由有限域 GF(28)上的乘法取逆和GF(2)上的仿射變換兩步組成。
2、行變換ShiftRows()

行變換是一種線性變換,其目的就是使密碼信息達到充分的混亂,提高非線形度。行變換對狀態的每行以字節爲單位進行循環右移,移動字節數根據行數來確定,第0行不發生偏移,第一行循環右移一個字節,第二行移兩個,依次類推。
3、 列混合變換MixColumns()

列變換就是從狀態中取出一列,表示成多項式的形式後,用它乘以一個固定的多項式a(x),然後將所得結果進行取模運算,模值爲 x4+1。其中a(x)={03}x3+{02}x2+{01}x+{02},
這個多項式與x4+1互質,因此是可逆的。列混合變換的算術表達式爲:s’(x)= a(x) s(x),其中, s(x)表示狀態的列多項式。
4、輪密鑰的添加變換AddRoundKey()
在這個操作中,輪密鑰被簡單地異或到狀態中,輪密鑰根據密鑰表獲得,其長度等於數據塊的長度Nb。
AES算法流程

對於發送方,它首先創建一個AES私鑰,並用口令對這個私鑰進行加密。然後把用口令加密後的AES密鑰通過Internet發送到接收方。發送方解密這個私鑰,並用此私鑰加密明文得到密文,密文和加密後的AES密鑰一起通過Internet發送到接收方。接收方收到後再用口令對加密密鑰進行解密得到AES密鑰,最後用解密後的密鑰把收到的密文解密成明文。圖7中是這個過程的實現流程。
AES算法流程

這裏寫圖片描述

RSA算法

RSA算法基本原理及流程

RSA是在1977年發明RSA密碼系統的三個人的名字的首字母的縮寫,他們是:Ron Rivest、Adi Shamir和Leonard Adleman。它是第一個公鑰加密算法,在很多密碼協議中都有應用,如SSL和S/MIME。RSA算法是基於大質數的因數分解的公匙體系。簡單的講,就是兩個很大的質數,一個作爲公鑰,另一個作爲私鑰,如用其中一個加密,則用另一個解密。密鑰長度從40到2048位可變,密鑰越長,加密效果越好,但加密解密的開銷也大。RSA算法可簡單描述如下:

公開密鑰:n=pq,(p,q爲兩個不同的很大的質數,p和q必須保密)
將(p-1)和(q-1)相乘得到φ(n)
選擇一個整數e (1<e<φ(n))與φ(n)互質
祕密密鑰:d=e-1modφ(n),即計算一個數字d,使得它滿足公式 de=1 modφ(n)
加密:c=mc(mod n) 
解密:m=cd(mod n),m爲明文,c爲密文。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

RSA算法實現流程

首先,接收方創建RSA密匙對,即一個公鑰和一個私鑰,公鑰被髮送到發送方,私鑰則被保存在接收方。發送方在接收到這個公鑰後,用該公鑰對明文進行加密得到密文,然後把密文通過網絡傳輸給接收方。接收方在收到它們後,用RSA私鑰對收到的密文進行解密,最後得到明文 下面 是整個過程的實現流程。

這裏寫圖片描述

AES與RSA相結合數據加密方案

RSA算法是公開密鑰系統的代表,其安全性建立在具有大素數因子的合數,其因子分解困難這一法則之上的。Rijndael算法作爲新一代的高級加密標準,運行時不需要計算機有非常高的處理能力和大的內存,操作可以很容易的抵禦時間和空間的攻擊,在不同的運行環境下始終能保持良好的性能。這使AES將安全,高效,性能,方便,靈活性集於一體,理應成爲網絡數據加密的首選。相比較,因爲AES密鑰的長度最長只有256比特,可以利用軟件和硬件實現高速處理,而RSA算法需要進行大整數的乘冪和求模等多倍字長處理,處理速度明顯慢於AES[5];所以AES算法加解密處理效率明顯高於RSA算法。在密鑰管理方面,因爲AES算法要求在通信前對密鑰進行祕密分配,解密的私鑰必須通過網絡傳送至加密數據接收方,而RSA採用公鑰加密,私鑰解密(或私鑰加密,公鑰解密),加解密過程中不必網絡傳輸保密的密鑰;所以RSA算法密鑰管理要明顯優於AES算法。

從上面比較得知,由於RSA加解密速度慢,不適合大量數據文件加密,因此在網絡中完全用公開密碼體制傳輸機密信息是沒有必要,也是不太現實的。AES加密速度很快,但是在網絡傳輸過程中如何安全管理AES密鑰是保證AES加密安全的重要環節。這樣在傳送機密信息的雙方,如果使用AES對稱密碼體制對傳輸數據加密,同時使用RSA不對稱密碼體制來傳送AES的密鑰,就可以綜合發揮AES和RSA的優點同時避免它們缺點來實現一種新的數據加密方案。

Android端 AES+RSA結合實踐

基本要求

保證傳輸數據的安全性
保證數據的完整性
能夠驗證客戶端的身份
基本流程

Android端

  1. 服務器端(server)分別生成自己的RSA密鑰對,並提供接口給Android客戶端獲取RSA公鑰(rsaPublicKey)
  2. client生成AES密鑰(aesKey)
  3. client使用自己的AES密鑰(aesKey)對轉換爲json格式的請求明文數據(data)進行加密,得到加密後的請求數據encryptData
  4. client提供server提供的接口獲取RSA公鑰(rsaPublicKey)
  5. client使用獲取RSA公鑰(rsaPublicKey)對AES密鑰(aesKey)進行加密,得到encryptAesKey
  6. client將encryptAesKey作爲http請求頭參數,將加密後的請求數據encryptData作爲請求體一起傳輸給服務器端
    服務器端

    1. server 響應client的http請求,讀取http請求頭。獲得client傳過來的加密後的AES密鑰(encryptAesKey),讀取http請求體,獲得client傳過來的加密後的請求數據(encryptData)。
    2. server使用自己的RSA私鑰(rsaPrivateKey)對加密後的AES密鑰(encryptAesKey)進行RSA解密,得到AES密鑰(aesKey)
    3. 使用解密後的AES密鑰(aesKey)對加密後的請求數據(encryptData),進行AES解密操作,得到解密後的請求數據(data),該數據爲json格式
    4. 對解密後的請求數據(data)進行json解析,然後做相關的響應操作。

這裏寫圖片描述

分享github上一個demon https://github.com/wustrive2008/aes-rsa-java

下面進入代碼實戰。

<一>. MD5加密算法:
消息摘要算法第五版(Message Digest Algorithm),是一種單向加密算法,只能加密、無法解密。然而MD5加密算法已經被中國山東大學王小云教授成功破譯哭,但是在安全性要求不高的場景下,MD5加密算法仍然具有應用價值。
1. 創建md5對象:

MessageDigest md5 = MessageDigest.getInstance(“md5”);
2. 進行加密操作:
byte[] cipherData = md5.digest(plainText.getBytes());

  1. 將其中的每個字節轉成十六進制字符串:byte類型的數據最高位是符號位,通過和0xff進行與操作,轉換爲int類型的正整數。
    Java代碼
    String toHexStr = Integer.toHexString(cipher & 0xff);
  2. 如果該正數小於16(長度爲1個字符),前面拼接0佔位:確保最後生成的是32位字符串。
    Java代碼
    builder.append(toHexStr.length() == 1 ? “0” + toHexStr : toHexStr);
  3. 加密轉換之後的字符串爲:c0bb4f54f1d8b14caf6fe1069e5f93ad
  4. 完整的MD5算法應用如下所示:
Java代碼 
/** 
 * 功能簡述: 測試MD5單向加密. 
 * @throws Exception 
 */  
@Test  
public void test01() throws Exception {  
    String plainText = "Hello , world !";  
    MessageDigest md5 = MessageDigest.getInstance("md5");  
    byte[] cipherData = md5.digest(plainText.getBytes());  
    StringBuilder builder = new StringBuilder();  
    for(byte cipher : cipherData) {  
        String toHexStr = Integer.toHexString(cipher & 0xff);  
        builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);  
    }  
    System.out.println(builder.toString());  
    //c0bb4f54f1d8b14caf6fe1069e5f93ad  
}  

<二>. 使用BASE64進行加密/解密:
使用BASE64算法通常用作對二進制數據進行加密,加密之後的數據不易被肉眼識別。嚴格來說,經過BASE64加密的數據其實沒有安全性可言保密,因爲它的加密解密算法都是公開的,典型的防菜鳥不防程序猿的呀。 經過標準的BASE64算法加密後的數據, 通常包含/、+、=等特殊符號,不適合作爲url參數傳遞,幸運的是Apache的Commons Codec模塊提供了對BASE64的進一步封裝。 (參見最後一部分的說明)
1. 使用BASE64加密:
Java代碼
BASE64Encoder encoder = new BASE64Encoder();
String cipherText = encoder.encode(plainText.getBytes());
2. 使用BASE64解密:
Java代碼
BASE64Decoder decoder = new BASE64Decoder();
plainText = new String(decoder.decodeBuffer(cipherText));
3. 完整代碼示例:
Java代碼

/** 
 * 功能簡述: 使用BASE64進行雙向加密/解密. 
 * @throws Exception 
 */  
@Test  
public void test02() throws Exception {  
    BASE64Encoder encoder = new BASE64Encoder();  
    BASE64Decoder decoder = new BASE64Decoder();  
    String plainText = "Hello , world !";  
    String cipherText = encoder.encode(plainText.getBytes());  
    System.out.println("cipherText : " + cipherText);  
    //cipherText : SGVsbG8gLCB3b3JsZCAh  
    System.out.println("plainText : " +   
        new String(decoder.decodeBuffer(cipherText)));  
    //plainText : Hello , world !

<三>. 使用DES對稱加密/解密:
數據加密標準算法(Data Encryption Standard),和BASE64最明顯的區別就是有一個工作密鑰,該密鑰既用於加密、也用於解密,並且要求密鑰是一個長度至少大於8位的字符串。使用DES加密、解密的核心是確保工作密鑰的安全性。叫
1. 根據key生成密鑰:
Java代碼

DESKeySpec keySpec = new DESKeySpec(key.getBytes());  
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des");  
SecretKey secretKey = keyFactory.generateSecret(keySpec);  
  1. 加密操作:
    Java代碼
Cipher cipher = Cipher.getInstance("des");  
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom());  
byte[] cipherData = cipher.doFinal(plainText.getBytes());  
  1. 爲了便於觀察生成的加密數據,使用BASE64再次加密:
String cipherText = new BASE64Encoder().encode(cipherData);  
 生成密文如下:PtRYi3sp7TOR69UrKEIicA== 

4. 解密操作:
Java代碼

cipher.init(Cipher.DECRYPT_MODE, secretKey, new SecureRandom());  
byte[] plainData = cipher.doFinal(cipherData);  
String plainText = new String(plainData);  
  1. 完整的代碼demo:
    Java代碼
/** 
 * 功能簡述: 使用DES對稱加密/解密. 
 * http://hello-nick-xu.iteye.com/blog/2103781
 * @throws Exception 
 */  
@Test  
public void test03() throws Exception {  
    String plainText = "Hello , world !";  
    String key = "12345678";    //要求key至少長度爲8個字符  

    SecureRandom random = new SecureRandom();  
    DESKeySpec keySpec = new DESKeySpec(key.getBytes());  
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des");  
    SecretKey secretKey = keyFactory.generateSecret(keySpec);  

    Cipher cipher = Cipher.getInstance("des");  
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, random);  
    byte[] cipherData = cipher.doFinal(plainText.getBytes());  
    System.out.println("cipherText : " + new BASE64Encoder().encode(cipherData));  
    //PtRYi3sp7TOR69UrKEIicA==  

    cipher.init(Cipher.DECRYPT_MODE, secretKey, random);  
    byte[] plainData = cipher.doFinal(cipherData);  
    System.out.println("plainText : " + new String(plainData));  
    //Hello , world !  
}  

<四>. 使用RSA非對稱加密/解密:
RSA算法是非對稱加密算法的典型代表,既能加密、又能解密。和對稱加密算法比如DES的明顯區別在於用於加密、解密的密鑰是不同的。使用RSA算法,只要密鑰足夠長(一般要求1024bit),加密的信息是不能被破解的。天真用戶通過https協議訪問服務器時,就是使用非對稱加密算法進行數據的加密、解密操作的。
服務器發送數據給客戶端時使用私鑰(private key)進行加密,並且使用加密之後的數據和私鑰生成數字簽名(digital signature)併發送給客戶端。客戶端接收到服務器發送的數據會使用公鑰(public key)對數據來進行解密,並且根據加密數據和公鑰驗證數字簽名的有效性,防止加密數據在傳輸過程中被第三方進行了修改。
客戶端發送數據給服務器時使用公鑰進行加密,服務器接收到加密數據之後使用私鑰進行解密。
1. 創建密鑰對KeyPair:
Java代碼

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("rsa");  
keyPairGenerator.initialize(1024);  //密鑰長度推薦爲1024位.  
KeyPair keyPair = keyPairGenerator.generateKeyPair();  
  1. 獲取公鑰/私鑰:
    Java代碼
PublicKey publicKey = keyPair.getPublic();  
PrivateKey privateKey = keyPair.getPrivate();  
  1. 服務器數據使用私鑰加密:
    Java代碼
Cipher cipher = Cipher.getInstance("rsa");  
cipher.init(Cipher.ENCRYPT_MODE, privateKey, new SecureRandom());  
byte[] cipherData = cipher.doFinal(plainText.getBytes());  
  1. 用戶使用公鑰解密:
    Java代碼
cipher.init(Cipher.DECRYPT_MODE, publicKey, new SecureRandom());  
byte[] plainData = cipher.doFinal(cipherData);  
  1. 服務器根據私鑰和加密數據生成數字簽名:
    Java代碼
Signature signature  = Signature.getInstance("MD5withRSA");  
signature.initSign(privateKey);  
signature.update(cipherData);  
byte[] signData = signature.sign(); 
  1. 用戶根據公鑰、加密數據驗證數據是否被修改過:
    Java代碼
signature.initVerify(publicKey);  
signature.update(cipherData);  
boolean status = signature.verify(signData);  
  1. RSA算法代碼demo
Java代碼 
/** 
 * 功能簡述: 使用RSA非對稱加密/解密. 
 * @throws Exception 
 */  
@Test  
public void test04() throws Exception {  
    String plainText = "Hello , world !";  

    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("rsa");  
    keyPairGenerator.initialize(1024);  
    KeyPair keyPair = keyPairGenerator.generateKeyPair();  

    PublicKey publicKey = keyPair.getPublic();  
    PrivateKey privateKey = keyPair.getPrivate();  

    Cipher cipher = Cipher.getInstance("rsa");  
    SecureRandom random = new SecureRandom();  

    cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);  
    byte[] cipherData = cipher.doFinal(plainText.getBytes());  
    System.out.println("cipherText : " + new BASE64Encoder().encode(cipherData));  
    //gDsJxZM98U2GzHUtUTyZ/Ir/NXqRWKUJkl6olrLYCZHY3RnlF3olkWPZ35Dwz9BMRqaTL3oPuyVq  
    //sehvHExxj9RyrWpIYnYLBSURB1KVUSLMsd/ONFOD0fnJoGtIk+T/+3yybVL8M+RI+HzbE/jdYa/+  
    //yQ+vHwHqXhuzZ/N8iNg=  

    cipher.init(Cipher.DECRYPT_MODE, publicKey, random);  
    byte[] plainData = cipher.doFinal(cipherData);  
    System.out.println("plainText : " + new String(plainData));  
    //Hello , world !  

    Signature signature  = Signature.getInstance("MD5withRSA");  
    signature.initSign(privateKey);  
    signature.update(cipherData);  
    byte[] signData = signature.sign();  
    System.out.println("signature : " + new BASE64Encoder().encode(signData));  
    //ADfoeKQn6eEHgLF8ETMXan3TfFO03R5u+cQEWtAQ2lRblLZw1DpzTlJJt1RXjU451I84v3297LhR  
    //co64p6Sq3kVt84wnRsQw5mucZnY+jRZNdXpcbwh2qsh8287NM2hxWqp4OOCf/+vKKXZ3pbJMNT/4  
    ///t9ewo+KYCWKOgvu5QQ=  

    signature.initVerify(publicKey);  
    signature.update(cipherData);  
    boolean status = signature.verify(signData);  
    System.out.println("status : " + status);  
    //true  
}  

下面給出工具類

package com.excelsoft.common.crypto;  

import java.io.IOException;  
import java.security.Key;  
import java.security.KeyPair;  
import java.security.KeyPairGenerator;  
import java.security.MessageDigest;  
import java.security.NoSuchAlgorithmException;  
import java.security.PrivateKey;  
import java.security.PublicKey;  
import java.security.SecureRandom;  
import java.security.Signature;  

import javax.crypto.Cipher;  
import javax.crypto.SecretKey;  
import javax.crypto.SecretKeyFactory;  
import javax.crypto.spec.DESKeySpec;  

import org.apache.commons.logging.Log;  
import org.apache.commons.logging.LogFactory;  

import sun.misc.BASE64Decoder;  
import sun.misc.BASE64Encoder;  

/** 
 * 功能簡述: 加密解密工具類,對MD5/BASE64/DES/RSA等算法提供了包裝. 
 * @author Nick Xu 
 * @version 1.0 
 */  
public class EncryptUtil {  
    private static Log logger = LogFactory.getLog(EncryptUtil.class);  

    private static final int KEY_SIZE = 1024;  
    private static final String  MD5_ALGORITHM= "md5";  
    private static final String  DES_ALGORITHM= "des";  
    private static final String  RSA_ALGORITHM= "rsa";  
    private static final String  SIGNATURE_ALGORITHM= "MD5withRSA";  

    private static MessageDigest md5;  
    private static BASE64Encoder encoder;  
    private static BASE64Decoder decoder;  
    private static SecureRandom random;  
    private static KeyPair keyPair;  

    private EncryptUtil() {  
    }  

    static {  
        try {  
            md5 = MessageDigest.getInstance(MD5_ALGORITHM);  

            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM);  
            keyPairGenerator.initialize(KEY_SIZE);  
            keyPair = keyPairGenerator.generateKeyPair();  
        }  
        catch (NoSuchAlgorithmException e) {  
            // Exception handler  
            logger.error(e);  
        }  
        encoder = new BASE64Encoder();  
        decoder = new BASE64Decoder();  
        random = new SecureRandom();  
    }  

    /** 
     * 功能簡述: 使用md5進行單向加密. 
     */  
    public static String encryptMD5(String plainText) {  
        byte[] cipherData = md5.digest(plainText.getBytes());  
        StringBuilder builder = new StringBuilder();  
        for(byte cipher : cipherData) {  
            String toHexStr = Integer.toHexString(cipher & 0xff);  
            builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);  
        }  
        return builder.toString();  
    }  

    /** 
     * 功能簡述: 使用BASE64進行加密. 
     * @param plainData 明文數據 
     * @return 加密之後的文本內容 
     */  
    public static String encryptBASE64(byte[] plainData) {  
        return encoder.encode(plainData);  
    }  

    /** 
     * 功能簡述: 使用BASE64進行解密. 
     * @param cipherText 密文文本 
     * @return 解密之後的數據 
     */  
    public static byte[] decryptBASE64(String cipherText) {  
        byte[] plainData = null;  
        try {  
            plainData =  decoder.decodeBuffer(cipherText);  
        }  
        catch (IOException e) {  
            // Exception handler  
            logger.error(e);  
        }  
        return plainData;  
    }  

    /** 
     * 功能簡述: 使用DES算法進行加密. 
     * @param plainData 明文數據 
     * @param key   加密密鑰 
     * @return   
     */  
    public static byte[] encryptDES(byte[] plainData, String key) {  
        return processCipher(plainData, createSecretKey(key), Cipher.ENCRYPT_MODE, DES_ALGORITHM);  
    }  

    /** 
     * 功能簡述: 使用DES算法進行解密. 
     * @param cipherData    密文數據 
     * @param key   解密密鑰 
     * @return 
     */  
    public static byte[] decryptDES(byte[] cipherData, String key) {  
        return processCipher(cipherData, createSecretKey(key), Cipher.DECRYPT_MODE, DES_ALGORITHM);  
    }  

    /** 
     * 功能簡述: 根據key創建密鑰SecretKey. 
     * @param key  
     * @return 
     */  
    private static SecretKey createSecretKey(String key) {  
        SecretKey secretKey = null;  
        try {  
            DESKeySpec keySpec = new DESKeySpec(key.getBytes());  
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);  
            secretKey = keyFactory.generateSecret(keySpec);  
        }  
        catch (Exception e) {  
            // Exception handler  
            logger.error(e);  
        }  
        return secretKey;  
    }  

    /** 
     * 功能簡述: 加密/解密處理流程. 
     * @param processData   待處理的數據 
     * @param key   提供的密鑰 
     * @param opsMode   工作模式 
     * @param algorithm   使用的算法 
     * @return   
     */  
    private static byte[] processCipher(byte[] processData, Key key, int opsMode, String algorithm) {  
        try{   
            Cipher cipher = Cipher.getInstance(algorithm);  
            cipher.init(opsMode, key, random);  
            return cipher.doFinal(processData);  
        }  
        catch (Exception e) {  
            // Exception handler  
            logger.error(e);  
        }  
        return null;  
    }  

    /** 
     * 功能簡述: 創建私鑰,用於RSA非對稱加密. 
     * @return 
     */  
    public static PrivateKey createPrivateKey() {  
        return keyPair.getPrivate();  
    }  

    /** 
     * 功能簡述: 創建公鑰,用於RSA非對稱加密. 
     * @return 
     */  
    public static PublicKey createPublicKey() {  
        return keyPair.getPublic();  
    }  

    /** 
     * 功能簡述: 使用RSA算法加密. 
     * @param plainData 明文數據 
     * @param key   密鑰 
     * @return 
     */  
    public static byte[] encryptRSA(byte[] plainData, Key key) {  
        return processCipher(plainData, key, Cipher.ENCRYPT_MODE, RSA_ALGORITHM);  
    }  

    /** 
     * 功能簡述: 使用RSA算法解密. 
     * @param cipherData    密文數據 
     * @param key   密鑰 
     * @return 
     */  
    public static byte[] decryptRSA(byte[] cipherData, Key key) {  
        return processCipher(cipherData, key, Cipher.DECRYPT_MODE, RSA_ALGORITHM);  
    }  

    /** 
     * 功能簡述: 使用私鑰對加密數據創建數字簽名. 
     * @param cipherData     已經加密過的數據 
     * @param privateKey    私鑰 
     * @return 
     */  
    public static byte[] createSignature(byte[] cipherData, PrivateKey privateKey) {  
        try {  
            Signature signature  = Signature.getInstance(SIGNATURE_ALGORITHM);  
            signature.initSign(privateKey);  
            signature.update(cipherData);  
            return signature.sign();  
        }  
        catch (Exception e) {  
            // Exception handler  
            logger.error(e);   
        }  
        return null;  
    }  

    /** 
     * 功能簡述: 使用公鑰對數字簽名進行驗證. 
     * @param signData  數字簽名 
     * @param publicKey 公鑰 
     * @return 
     */  
    public static boolean verifySignature(byte[] cipherData, byte[] signData, PublicKey publicKey) {  
        try {  
            Signature signature  = Signature.getInstance(SIGNATURE_ALGORITHM);  
            signature.initVerify(publicKey);  
            signature.update(cipherData);  
            return signature.verify(signData);  
        }  
        catch (Exception e) {  
            // Exception handler  
            logger.error(e);  
        }  
        return false;  
    }  
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章