Java 與 iOS使用RSA 加密簽名

RSA算法是一種非對稱加密算法,常被用于加密數據傳輸.如果配合上數字摘要算法, 也可以用于文件簽名.

本文將討論如何在iOS中使用RSA傳輸加密數據.

本文環(huán)境

mac os
openssl-1.0.1j, openssl需要使用1.x版本, 推薦使用homebrew安裝.
Java 8

RSA基本原理

RSA使用"秘匙對"對數據進行加密解密.在加密解密數據前,需要先生成公鑰(public key)和私鑰(private key).

公鑰(public key): 用于加密數據. 用于公開, 一般存放在數據提供方, 例如iOS客戶端.
私鑰(private key): 用于解密數據. 必須保密, 私鑰泄露會造成安全問題.
iOS中的Security.framework提供了對RSA算法的支持.這種方式需要對密匙對進行處理, 根據public key生成證書, 通過private key生成p12格式的密匙.

除了Secruty.framework, 也可以 將openssl庫編譯到iOS工程中 , 這可以提供更靈活的使用方式.

本文使用Security.framework的方式處理RSA.

使用openssl生成密匙對

Github Gist: https://gist.github.com/lvjian700/635368d6f1e421447680

#!/usr/bin/env bash
echo "Generating RSA key pair ..."
echo "1024 RSA key: private_key.pem"
openssl genrsa -out private_key.pem 1024

echo "create certification require file: rsaCertReq.csr"
openssl req -new -key private_key.pem -out rsaCertReq.csr

echo "create certification using x509: rsaCert.crt"
openssl x509 -req -days 3650 -in rsaCertReq.csr -signkey private_key.pem -out rsaCert.crt

echo "create public_key.der For IOS"
openssl x509 -outform der -in rsaCert.crt -out public_key.der

echo "create private_key.p12 For IOS. Please remember your password. The password will be used in iOS."
openssl pkcs12 -export -out private_key.p12 -inkey private_key.pem -in rsaCert.crt

echo "create rsa_public_key.pem For Java"
openssl rsa -in private_key.pem -out rsa_public_key.pem -pubout
echo "create pkcs8_private_key.pem For Java"
openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt

echo "finished."

Tips:

  • 在創(chuàng)建證書的時候, terminal會提示輸入證書信息. 根據wizard輸入對應信息就OK.
  • 在創(chuàng)建p12密匙時, 會提示輸入密碼, 此時的密碼必須記住, 之后會用到.
  • 如果上面指令有問題,請參考最新的openssl官方文檔, 以官方的為準. 之前在網上搜索指令, 被坑了一圈之后, 還是會到啃官方文檔上. 每條指令文檔在最后都會有幾個sample,參考sample即可.

iOS如何加載使用證書

將下面代碼添加到項目中:

https://gist.github.com/lvjian700/204c23226fdffd6a505d

代碼依賴 Base64編碼庫 , 如果使用cocoapods, 可以講下面依賴添加到Podfile:

pod 'Base64nl', '~> 1.2'

加密數據

RSAEncryptor *rsa = [[RSAEncryptor alloc] init];
  NSLog(@"encryptor using rsa");
  NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"];
  NSLog(@"public key: %@", publicKeyPath);
  [rsa loadPublicKeyFromFile:publicKeyPath];
  NSString *securityText = @"hello ~";
  NSString *encryptedString = [rsa rsaEncryptString:securityText];
  NSLog(@"encrypted data: %@", encryptedString);

[rsa rsaEncryptString:securityText]會返回decrypted base64編碼的字符串:

console out 寫道

encrypted data: I1Mnu33cU7QcgaC9uo2bxV0vyfJSqAwyC3DZ+p8jm0G2EmcClarrR5R2xLDdXqvtKj+UJbES7TT+AgkK1NDoQvOJBY+jkmrpAchmRbV2jvi3cEZYQG955jrdSAu21NzQe8xWtEc3YzP+TACPdP4B3Cyy0u8N2RcSFWyxu0YKPXE=

解密數據

在iOS下解碼需要先加載private key, 之后在對數據解碼. 解碼的時候先進行Base64 decode, 之后在用private key decrypt加密數據.

NSLog(@"decryptor using rsa");
    [rsa loadPrivateKeyFromFile:[[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"p12"] password:@"123456"];
    NSString *decryptedString = [rsa rsaDecryptString:encryptedString];
    NSLog(@"decrypted data: %@", decryptedString);

之后會輸出解密后的數據:

console 寫道

decryptor using rsadecrypted data: hello ~

在服務器端解碼數據 ** (Java) **

在Java中解碼需要使用下述指令生成的pkcs8 private key:

gen shell 寫道

openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt

具體解碼步驟:

加載pkcs8 private key:
讀取private key文件
去掉private key頭尾的"-----BEGIN PRIVATE KEY-----"和"-----BEGIN PRIVATE KEY-----"
刪除private key中的換行
對處理后的數據進行Base64解碼
使用解碼后的數據生成private key.
解密數據:
對數據進行Base64解碼
使用RSA decrypt數據.
這里我將iOS中"hello ~"加密的數據在Java中進行解碼:

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import static java.lang.String.format;
public class Encryptor {
    public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
  PrivateKey privateKey = readPrivateKey();
  String message = "AFppaFPTbmboMZD55cjCfrVaWUW7+hZkaq16Od+6fP0lwz/yC+Rshb/8cf5BpBlUao2EunchnzeKxzpiPqtCcCITKvk6HcFKZS0sN9wOhlQFYT+I4f/CZITwBVAJaldZ7mkyOiuvM+raXMwrS+7MLKgYXkd5cFPxEsTxpMSa5Nk=";
  System.out.println(format("- decrypt rsa encrypted base64 message: %s", message));
  // hello ~,  encrypted and encoded with Base64:
  byte[] data = encryptedData(message);
  String text = decrypt(privateKey, data);
  System.out.println(text);
    }
    private static String decrypt(PrivateKey privateKey, byte[] data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
  Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
  cipher.init(Cipher.DECRYPT_MODE, privateKey);
  byte[] decryptedData = cipher.doFinal(data);
  return new String(decryptedData);
    }
    private static byte[] encryptedData(String base64Text) {
  return Base64.getDecoder().decode(base64Text.getBytes(Charset.forName("UTF-8")));
    }
    private static PrivateKey readPrivateKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
  byte[] privateKeyData = Files.readAllBytes(
    Paths.get("/Users/twer/macspace/ios_workshop/Security/SecurityLogin/tools/pkcs8_private_key.pem"));
  byte[] decodedKeyData = Base64.getDecoder()
    .decode(new String(privateKeyData)
      .replaceAll("-----\\w+ PRIVATE KEY-----", "")
      .replace("\n", "")
      .getBytes());
  return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decodedKeyData));
    }
}

直行成功后控制臺會輸出"hello ~".

總結

這種加密傳輸方式會被用在網銀類App中.雖然網銀會采用全站https方案, 但是在安全登錄這塊會使用另一個證書對登錄信息加密, 這樣可以雙層確保數據安全.

基于RSA加密解密算法, 還可以將其運用在數字簽名場景.以后有空在聊如何使用RSA算法實現對文件的數字簽名.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子蹲姐,更是在濱河造成了極大的恐慌傍念,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件控妻,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機对雪,發(fā)現死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來米绕,“玉大人瑟捣,你說我怎么就攤上這事≌じ桑” “怎么了蝶柿?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長非驮。 經常有香客問我交汤,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任芙扎,我火速辦了婚禮星岗,結果婚禮上,老公的妹妹穿的比我還像新娘戒洼。我一直安慰自己俏橘,他們只是感情好,可當我...
    茶點故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布圈浇。 她就那樣靜靜地躺著寥掐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪磷蜀。 梳的紋絲不亂的頭發(fā)上召耘,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天柏锄,我揣著相機與錄音愿阐,去河邊找鬼。 笑死驼鞭,一個胖子當著我的面吹牛庶弃,可吹牛的內容都是我干的衫贬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼歇攻,長吁一口氣:“原來是場噩夢啊……” “哼固惯!你這毒婦竟也來了?” 一聲冷哼從身側響起缴守,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤葬毫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后斧散,有當地人在樹林里發(fā)現了一具尸體供常,經...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年鸡捐,在試婚紗的時候發(fā)現自己被綠了栈暇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡箍镜,死狀恐怖源祈,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情色迂,我是刑警寧澤香缺,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站歇僧,受9級特大地震影響图张,放射性物質發(fā)生泄漏锋拖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一祸轮、第九天 我趴在偏房一處隱蔽的房頂上張望兽埃。 院中可真熱鬧,春花似錦适袜、人聲如沸柄错。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽售貌。三九已至,卻和暖如春疫萤,著一層夾襖步出監(jiān)牢的瞬間颂跨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工给僵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留毫捣,地道東北人详拙。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓帝际,卻偏偏與公主長得像,于是被迫代替她去往敵國和親饶辙。 傳聞我的和親對象是個殘疾皇子蹲诀,可洞房花燭夜當晚...
    茶點故事閱讀 44,665評論 2 354

推薦閱讀更多精彩內容

  • 概述 之前一直對加密相關的算法知之甚少,只知道類似DES弃揽、RSA等加密算法能對數據傳輸進行加密脯爪,且各種加密算法各有...
    Henryzhu閱讀 3,019評論 0 14
  • RSA算法是一種非對稱加密算法,常被用于加密數據傳輸.如果配合上數字摘要算法, 也可以用于文件簽名. 本文將討論如...
    lvjian700閱讀 12,271評論 13 17
  • /**ios常見的幾種加密方法: 普通的加密方法是講密碼進行加密后保存到用戶偏好設置( [NSUserDefaul...
    彬至睢陽閱讀 2,927評論 0 7
  • 如今人們日常工作中使用的電腦顯示器都已經普及成LED顯示屏了。我們在長時間盯著顯示器后會感覺眼睛干澀矿微,流淚痕慢。這背后...
    十六畫生的寫作閱讀 961評論 0 3
  • 1掖举、碎片化并不是什么問題,問題是你的學習也是碎片化的娜庇。 不知道大家有沒有這樣的感受塔次,就是我們的時間被碎片化了。我們...
    沫小神閱讀 640評論 0 2