Java/Android加密相關(guān)

最近在看HTTPS,其核心還是基與Rsa加密的SSL/TSL,所以整理一下在Android開發(fā)中常見的幾種加密方式

  • MD5
  • BASE64
  • AES
  • DES
  • RSA
  • SSL/TSL

MD5加密

MD5英文全稱Message-Digest Algorithm 5,全稱消息算法摘要,是一種不可逆加密方式

特點

  • 壓縮性:任意長度的數(shù)據(jù)椰于,算出的MD5值長度都是固定的洞豁。
  • 容易計算:從原數(shù)據(jù)計算出MD5值很容易影兽。
  • 抗修改性:對原數(shù)據(jù)進行任何改動坤溃,哪怕只修改1個字節(jié)播揪,所得到的MD5值都有很大區(qū)別徒爹。
  • 強抗碰撞:已知原數(shù)據(jù)和其MD5值苍柏,想找到一個具有相同MD5值的數(shù)據(jù)(即偽造數(shù)據(jù))是非常困難的宜岛。

因為其特點,MD5加密通常用來驗證文件的完整性,防串改.

實現(xiàn)

在Java中提供了MessageDigest類來加密數(shù)據(jù).

byte[] resource; //需要加密的數(shù)據(jù)
MessageDigest md5=MessageDigest.getInstance("MD5");
byte[] bytes=md5.digest(resource);
StringBuilder builder=new StringBuilder(bytes.lenght);
for (byte byte :bytes ) {
 String temp = Integer.toHexString(b & 0xff);
 if (temp.lenght==1) {
     builder.append(0);
 }
    builder.append(temp);
}
String MD5=builder.toString();

MD5加密是對字節(jié)數(shù)組進行操作的.所以無論加密文件或是其它都需要先轉(zhuǎn)換為字節(jié)數(shù)組.加密后的結(jié)果也是字節(jié)數(shù)組.
為了方便查看,需要按規(guī)定轉(zhuǎn)換為字節(jié)數(shù)組.

BASE64

BASE64并不是一種加密方式,而是對字節(jié)數(shù)組的一種編碼方式.實際上是讓字節(jié)數(shù)據(jù)轉(zhuǎn)換為文本的方案.

原理

BASE64是把字節(jié)數(shù)據(jù)轉(zhuǎn)換為ASC碼中對應(yīng)的64個字符(英文大小寫,+及/).
轉(zhuǎn)換方式為每6位字節(jié)對應(yīng)一個字符.不足位的后面補0.6位字節(jié)轉(zhuǎn)換為十進制數(shù)值.范圍是0-63,對應(yīng)64個字符.如果有不足位的,在編碼后會補上數(shù)量對應(yīng)的=

用處

  • 統(tǒng)一編碼方式,不需要考慮字符集對數(shù)據(jù)的影響
  • 可以把任何文件或數(shù)據(jù)都以紡一的文本方式保存

實現(xiàn)

在Java中提供了Base64類來實現(xiàn)編碼轉(zhuǎn)換

//編碼
String encode= Base64.encode(byte[] bytes,int flag);
//解碼
byte[] decode=Base64.decode(byte[] bytes,int flag);

flag表示編碼方式,通常使用Base64.DEFAULT

  • Base64.DEFAULT 默認(rèn)的編碼方式
  • Base64.NO_PADDING 忽略后綴的=號
  • Base64.NO_WRAP 省略換行符
  • Base64.CTRL 使用微軟的換行符,而不是Liunux的
  • Base64.URL_SAFE 使用-和_代替+和/以保證在URL的安全.通常用與網(wǎng)絡(luò)傳輸

AES

Advanced Encryption Standard,全稱為高級加密標(biāo)準(zhǔn),又稱為 Rijndael 加密法,使用的是區(qū)塊加密方案.
區(qū)塊加密方案是把一定數(shù)量的字節(jié)劃分為一個區(qū)塊,把區(qū)塊內(nèi)的數(shù)據(jù)加密成相同位數(shù)的數(shù)據(jù)
AES是一種對稱加密方案,所以需要加密端和解密端都使用相同的密鑰.

特點

  • 區(qū)塊 AES是對字節(jié)數(shù)組按區(qū)塊劃分,對區(qū)塊進行加密.AES區(qū)塊大小固定為128位.
  • 密鑰 AES的密鑰長度有三種,128位/192位/256位 位數(shù)越多安全性越高.
  • 矩陣 AES每次對區(qū)塊中的16個字節(jié)進行操作,這4個字節(jié)會組成一個4x4的矩陣.
  • 回合密鑰 AES對每個矩陣的操作時都會根據(jù)密鑰生成一個16位的回合密鑰.對應(yīng)矩陣上的每一個字節(jié)

實現(xiàn)

在Java中通過MessageDigest來進行AES加解密

//密鑰原數(shù)據(jù)字符串,兩端必須一樣,128位的密鑰字符串長度必須為16
private static final String KEY=""
//加密方式,AES表示AES加密,CBC表示區(qū)塊的處理方式,PKC5Padding表示區(qū)塊的填充方式.
private static final String MODE="AES/CBC/PKCS5Padding"

//生成密鑰
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY);
SecretKey secretKey = keyGenerator.generateKey();
//初始化密碼處理類
Cipher cipher = Cipher.getInstance(MODE);
cipher.init(Cipher.ENCRIPT_MODE,secretKey);  //第一個參數(shù)為模式,ENCRIPT_MODE為加密, DECRIPT為解密
//cipher.init(Cipher.DECRIPT_MODE,secretKey,"BC");  使用`PKCS7Padding`方式時需要加載bouncycastle包,BC為提供該填充方式的Provicer
byte[] date=cipher.doFinal(byte[] data); //加密和解密都是同一個方法,由初始化的模式?jīng)Q定.對源字節(jié)數(shù)組進行處理.生成新的字節(jié)數(shù)組.

填充方式有幾種.Java6沒有實現(xiàn)所有的填充方式.

  • NoPadding,PKCS5Padding,ISO10126Padding Java6實現(xiàn)
  • PKCS7Padding,ZeroBytePadding 需要加載bouncycastle

生成密鑰時,getInstance()有個重載的方法可以添加一個provier.為密鑰添加一個隨機數(shù).
AES加密安全性高,速度快.

DES

Data Encryption Standard,標(biāo)準(zhǔn)加密算法.使用64位密鑰的對稱加密.使用的也是區(qū)塊加密方案.
因為是64位密鑰,安全性不高,現(xiàn)已經(jīng)被AES加密替代.
實現(xiàn)方法同AES加密,只需要把MODE中的AES改為DES

RSA

目前使用最廣泛的非對稱加密.生成一對密鑰--公鑰和私鑰.公鑰對來對外提供.私鑰只有密鑰生成者自己擁有
非對稱算法需要指定密鑰長度,越長安全性越好,但加解密的速度就越慢.通常指定1024或2048.
一次加密的的密文長度為密鑰長度/8-11,所以1024長度的密鑰一次只能加密117字節(jié).2048能加密245字節(jié).
所以非對稱加密通常只用與短數(shù)據(jù)加密,如簽名或?qū)ΨQ加密的密鑰.
RSA加密都是一用與一對多的場景.
RSA有兩種使用方式

  • 加密算法
    公鑰加密,只有私鑰才能解密
  • 簽名算法
    私鑰簽名,只有公鑰才能驗證.
    如Github使用的SSH登錄就是使用的RSA加密算法.用戶把公鑰保存到服務(wù)器,
    通過SSH登錄時服務(wù)器發(fā)一個隨機數(shù)給客戶端,客戶端使用私鑰加密發(fā)送到服務(wù)器,服務(wù)器用保存的公鑰解密.

RSA的密鑰的產(chǎn)生

  • 隨機獲取兩個大質(zhì)數(shù),得其積N
  • 獲取N的歐拉函數(shù)值->整數(shù)R
  • 隨機獲取一個小與R并與之互質(zhì)的整數(shù)E,計算出E的反模元素D
  • 公鑰是(N,E),私鑰是(N,D)

RSA的原理

  • 歐拉定理
    兩個互質(zhì)的正整數(shù),A和N,N的歐拉函數(shù)為P,則A的P次方除以N余1
  • 費馬小定理(RSA算法核心)
    因為質(zhì)數(shù)P的歐拉函數(shù)為P-1,所以一個整數(shù)A和一個質(zhì)數(shù)N互質(zhì)時,A的N-1次方除以N余1
  • 反模元素
    兩個互質(zhì)的正整數(shù).A和N,則一定存在一個整數(shù)B,使得A乘B除以N余數(shù)為1

實現(xiàn)

定義常量

private static final KEY_SIZE=1024;
private static final RSA="RSA";
private static final MODE="RSA/ECB/PCKS1Padding"

這里注意RSA的加密填充方式,需要兩端保持一至.
在Adrioid中默認(rèn)使用的是RSA/None/NoPadding,在Java中使用的是RSA/None/PCKS1Padding.

創(chuàng)建密鑰

KeyPairGenerator rsa = KeyPairGenerator.getInstance(RSA);
rsa.initialize(KEY_SIZE);
KeyPair keyPair = rsa.generateKeyPair();
Key publicKey = keyPair.getPublic();
byte[] publicKeyEncoded = publicKey.getEncoded();
Key privateKey = keyPair.getPrivate();
byte[] privateKeyEncoded = privateKey.getEncoded();

把字節(jié)數(shù)組轉(zhuǎn)換為Key

公鑰會以字節(jié)數(shù)組的形式公開.接收方需要把字節(jié)數(shù)據(jù)轉(zhuǎn)化為公鑰

//公鑰公開的方式為X509
KeySpec KeySpec = new X509EncodedKeySpec(publicKeyEncoded);
PublicKey publicKey = keyFactory.generatePublic(keySpec);
//私鑰公開的方式為PKCS8
KeySpec keySpec = new PKCS8EncodedKeySpec(publicKeyEncoded);
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

加解密

通常使用公鑰加密,使用私鑰解密.還是使用Cipher

Cipher cipher=Cipher.instance(MODE);
//使用公鑰加密
cipher.init(Cipher.ENCRIPT_MODE,publicKey);
cipher.doFinal();
//使用私鑰解密
cipher.init(Cipher.DECRIPT_MODE,privateKey);
cipher.doFinal();

SSL

安全套接字(Secure Socket Layer,SSL)協(xié)議是Web瀏覽器與Web服務(wù)器之間安全交換信息的協(xié)議囱怕,提供兩個基本的安全服務(wù):鑒別與保密霍弹。

  • 鑒別 可選的客戶端認(rèn)證及強制的服務(wù)端認(rèn)證
  • 保密 雙方在連接時定義好加密方式,所有傳遞內(nèi)容都會加密.

SSL是間與應(yīng)用層與TCP層.應(yīng)用數(shù)據(jù)經(jīng)過SSL層加密并加上SSL頭傳輸給TCP層.

SSL通信流程

  • 握手
    握手是在兩端連接后數(shù)據(jù)傳輸前的協(xié)議行為,通過三次握手確定雙方的身份,雙方的加密方式,以及確定密鑰.這個握手過程是通過RAS加密及身份證書完成的.
  • 加密通信
    完成握手協(xié)議手,雙方就按確定的加密方式以對稱加密的方式對數(shù)據(jù)進行加密

握手協(xié)議

  • 客戶端發(fā)送至服務(wù)器 一個會話ID,自身SSL版本.一個32位隨機數(shù).一自身支持的密碼套件列表.一個hello.
  • 服務(wù)器接收后會根據(jù)客戶端提供的列表選擇一個密碼套件,確定與客戶端之間的加密方式
  • 服務(wù)器發(fā)送至客戶端 會話ID,SSL版本,一個32位隨機數(shù),一個密碼套件.一個servieHello.及自己的證書.
  • 客戶端收到證書后可以對證書進行驗證.然后生成一個32位隨機數(shù).這樣總共就有三個隨機數(shù)了.根據(jù)服務(wù)端確定的加密方式用這三個隨機數(shù)生成密鑰.然后從證書中獲得服務(wù)端的公鑰對第三個隨機數(shù)加密
  • 客戶端發(fā)送至服務(wù)器 加密的第三個隨機數(shù).
  • 服務(wù)器收到加密的隨機數(shù)后使用私鑰解密,然后使用三個隨機數(shù)生成密鑰.
  • 服務(wù)器發(fā)送至客戶端 準(zhǔn)備完成,可以開始加密通信

證書

證書是一臺服務(wù)器對外提供的一個身份證明.需要通過可靠的第三方認(rèn)證機構(gòu)(CA)來發(fā)布.
一個數(shù)字證書通常有以下幾項

  • 證書持有者的公鑰
  • 證書的發(fā)布機構(gòu)
  • CA的簽名
  • 簽名摘要的算法

證書的驗證

一般的瀏覽器都會有CA根證書,含有所有CA的公鑰

  • CA驗證 CA根證書中找到不證書的發(fā)布機構(gòu)
  • CA簽名摘要驗證 使用CA的公鑰來解密簽名摘要,如果解不開說明證書不對
  • CA簽名驗證 使用公鑰解密簽名.然后使用簽名摘要算法進行簽名摘要,比對解密手的簽名摘要.如果不同說明簽名被更改
  • 證書過期驗證 實現(xiàn)了在線證書狀態(tài)協(xié)議(OCSP)的客戶端可以在線查詢證書是否過期

TSL

TLS 1.0是IETF(Internet Engineering Task Force,Internet工程任務(wù)組)制定的一種新的協(xié)議娃弓,它建立在SSL 3.0協(xié)議規(guī)范之上典格,是SSL 3.0的后續(xù)版本,可以理解為SSL 3.1

原文地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末台丛,一起剝皮案震驚了整個濱河市耍缴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挽霉,老刑警劉巖防嗡,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異侠坎,居然都是意外死亡蚁趁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門实胸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來他嫡,“玉大人,你說我怎么就攤上這事庐完「质簦” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵门躯,是天一觀的道長淆党。 經(jīng)常有香客問我,道長生音,這世上最難降的妖魔是什么宁否? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮缀遍,結(jié)果婚禮上慕匠,老公的妹妹穿的比我還像新娘。我一直安慰自己域醇,他們只是感情好台谊,可當(dāng)我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布蓉媳。 她就那樣靜靜地躺著,像睡著了一般锅铅。 火紅的嫁衣襯著肌膚如雪酪呻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天盐须,我揣著相機與錄音玩荠,去河邊找鬼。 笑死贼邓,一個胖子當(dāng)著我的面吹牛阶冈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播塑径,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼女坑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了统舀?” 一聲冷哼從身側(cè)響起匆骗,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎誉简,沒想到半個月后碉就,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡描融,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年铝噩,在試婚紗的時候發(fā)現(xiàn)自己被綠了衡蚂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窿克。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖毛甲,靈堂內(nèi)的尸體忽然破棺而出年叮,到底是詐尸還是另有隱情,我是刑警寧澤玻募,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布只损,位于F島的核電站,受9級特大地震影響七咧,放射性物質(zhì)發(fā)生泄漏跃惫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一艾栋、第九天 我趴在偏房一處隱蔽的房頂上張望爆存。 院中可真熱鬧,春花似錦蝗砾、人聲如沸先较。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闲勺。三九已至曾棕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間菜循,已是汗流浹背翘地。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留癌幕,地道東北人子眶。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像序芦,于是被迫代替她去往敵國和親臭杰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容

  • 目錄 準(zhǔn)備 分析2.1. 三次握手2.2. 創(chuàng)建 HTTP 代理(非必要)2.3. TLS/SSL 握手2.4. ...
    RunAlgorithm閱讀 38,060評論 12 117
  • 這篇文章主要講述在Mobile BI(移動商務(wù)智能)開發(fā)過程中谚中,在網(wǎng)絡(luò)通信渴杆、數(shù)據(jù)存儲、登錄驗證這幾個方面涉及的加密...
    雨_樹閱讀 2,371評論 0 6
  • 數(shù)據(jù)傳輸加密 在開發(fā)應(yīng)用過程中宪塔,客戶端與服務(wù)端經(jīng)常需要進行數(shù)據(jù)傳輸磁奖,涉及到重要隱私信息時,開發(fā)者自然會想到對其進行...
    chaychan閱讀 6,958評論 8 93
  • 今天大boss給我分配了一個小領(lǐng)導(dǎo)某筐。聽說這個小領(lǐng)導(dǎo)有點色比搭,這讓我有些害怕。 雖然害怕南誊,但還不至于軟弱身诺。我雖然為人很...
    廬山謠閱讀 329評論 0 0
  • 六點半出發(fā),從約克到愛丁堡抄囚。 早起不是特別痛苦霉赡,還在倒時差,五點起床的時候幔托,相當(dāng)于國內(nèi)中午1點穴亏。 從約克到愛丁堡大...
    MrCooper閱讀 551評論 0 0