Java RSA公鑰加密,私鑰解密算法的嘗試
https://www.cnblogs.com/liemng/p/6699257.html
寫這篇博客其實是有點意外的,來源最初也算是入職當前這家公司算吧,由於項目要求數據幾乎都進行了加密(政府項目麽!!!),當時看到這塊就想好好看看這塊的東西,苦於時間一直尋找不開,慢慢的都忘記了,忽然有天在網上看到一些關於加密的博客,討論到說支付寶這樣的商業軟件加密是如何進行操作,後來了解了下,由於我是做android開發的所以我想當然的就下載了一個支付寶的android版本,進階著就是迫不及待的改後綴,然後看看內部構造,發現支付寶的.so文件是超級多,那麽問題來了,對於支付寶這樣當量的用戶,放到android 的java層去加密肯定是不合適的,這裏來源於java語言的不安全性的考慮。多的不說apk的反編譯,一旦反編譯了看到了你java加密算法,臥槽,那問題就大了去了,估計馬雲爸爸想殺人的新都有,那麽很顯然對於支付寶而言肯定不能這麽幹,那麽多的.so就很能說明問題了(加密是通過jni使用C代碼實現的加密)。
那麽到了這裏加密基本算是確認了,要是想保證你的數據的安全放到.so裏會更加的安全(android上才有的東西哈).
說道加密那麽就進入到本篇博客的主題,加密算法之RSA非對稱的加密算法。直譯為私鑰加密,公鑰解密。其實也是很簡單了,私鑰只要你自己知道就好了,這樣就能保證加密的數據只能你自己才能解密。公鑰可以公開,公鑰僅僅是用於加密的,是無法用於去解密數據的。
RSA非對稱的算法,也是不可逆的,不可逆就是無法根據公鑰得到其算法,然後根據公鑰去獲去私鑰!!!
好了 ,基本的講解就這些吧,緊接著一起來看下關於Java中的一些RSA的使用吧!!!
Java使用分為三步走戰略!!!
1,生成私鑰和秘鑰
2,公鑰加密
3,私鑰解密
看到這裏是不是很so easy.
java代碼生成私鑰和秘鑰如下代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/**
*生成私鑰 公鑰
*/
public static void geration(){
KeyPairGenerator keyPairGenerator;
try {
keyPairGenerator = KeyPairGenerator.getInstance( "RSA" );
SecureRandom secureRandom = new SecureRandom( new Date().toString().getBytes());
keyPairGenerator.initialize( 1024 , secureRandom);
KeyPair keyPair = keyPairGenerator.genKeyPair();
byte [] publicKeyBytes = keyPair.getPublic().getEncoded();
FileOutputStream fos = new FileOutputStream(PUBLIC_KEY_PATH);
fos.write(publicKeyBytes);
fos.close();
byte [] privateKeyBytes = keyPair.getPrivate().getEncoded();
fos = new FileOutputStream(PRIVATE_KEY_PATH);
fos.write(privateKeyBytes);
fos.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
|
獲去公鑰代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/**
* 獲取公鑰
* @param filename
* @return
* @throws Exception
*/
public static PublicKey getPublicKey(String filename) throws Exception {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte [] keyBytes = new byte [( int )f.length()];
dis.readFully(keyBytes);
dis.close();
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance( "RSA" );
return kf.generatePublic(spec);
}
|
獲去私鑰的代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/**
* 獲取私鑰
* @param filename
* @return
* @throws Exception
*/
public static PrivateKey getPrivateKey(String filename) throws Exception {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte [] keyBytes = new byte [( int )f.length()];
dis.readFully(keyBytes);
dis.close();
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance( "RSA" );
return kf.generatePrivate(spec);
}
|
測試如上代碼的可用性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public static void main(String[] args) {
geration();
String input = "!!!hello world!!!" ;
RSAPublicKey pubKey;
RSAPrivateKey privKey;
byte [] cipherText;
Cipher cipher;
try {
cipher = Cipher.getInstance( "RSA" );
pubKey = (RSAPublicKey) getPublicKey(PUBLIC_KEY_PATH);
privKey = (RSAPrivateKey) getPrivateKey(PRIVATE_KEY_PATH);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
cipherText = cipher.doFinal(input.getBytes());
//加密後的東西
System.out.println( "cipher: " + new String(cipherText));
//開始解密
cipher.init(Cipher.DECRYPT_MODE, privKey);
byte [] plainText = cipher.doFinal(cipherText);
System.out.println( "publickey: " + Base64.getEncoder().encode(cipherText));
System.out.println( "plain : " + new String(plainText));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
|
測試結果如下:
1 2 3 |
cipher: D?:?=羖O縜?,^辀?$偞/致? 2 懁B鏣靴臧?? 2 e嗀|?,w饞i纂W俞:&圼?G6?弒橰H桞℉鬜?=)^呸b???;皒Ddm`苣+.+?
?:& ??#f-?扴8eE]?(
plain : !!!hello world!!!
|
如上是RSA加密的java版本
當然上述最終生成的byte寫入到了一個文件中。如果你感覺這樣和你不方便你也可以直接用base64編碼成一個字符串,保留下來。
1 2 3 |
使用Base64.getEncoder().encodeToString(keyBytes)進行編譯
使用Base64.getDecoder().decode(PUBLIC_KEY)進行解碼
|
Java RSA公鑰加密,私鑰解密算法的嘗試