前沿拓展:
數(shù)據(jù)信息安全對我們每個(gè)人都有很重要的意義,特別是一些敏感信息,可能一些類似于收貨地址、手機(jī)號還沒引起大家的注意。但是最直白的,銀行卡、姓名、手機(jī)號、身份證號,如果這些信息被黑客攔截到,他就可以偽裝成你,把你的錢都取走。那我們該怎么防止這樣的事情發(fā)生?報(bào)文加密解密,加簽驗(yàn)簽。
(String context, byte[] desKey) throws Exception { byte[] encryptResult = des(context.getBytes("UTF-8"), desKey, 1); return Hex.encodeHexString(encryptResult); } private static byte[] des(byte[] inputBytes, byte[] keyBytes, int mode) throws Exception { DESKeySpec desKeySpec = new DESKeySpec(keyBytes); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = keyFactory.generateSecret(desKeySpec); IvParameterSpec iv = new IvParameterSpec(keyBytes); Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(mode, secretKey, iv); return cipher.doFinal(inputBytes); }銀行的公鑰+會話密鑰desKey非對稱加密得到加密后的會話密鑰key/** * RAS加密 * * @return byte[]*/
public byte[] encryptRSA(byte[] plainBytes, boolean useBase64Code, String charset)
throws Exception {
String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding"; // 加密block需要預(yù)留11字節(jié)
int KEYBIT = 2048;
int RESERVEBYTES = 11;
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
int decryptBlock = KEYBIT / 8; // 256 bytes
int encryptBlock = decryptBlock – RESERVEBYTES; // 245 bytes
// 計(jì)算分段加密的block數(shù) (向上取整)
int nBlock = (plainBytes.length / encryptBlock);
if ((plainBytes.length % encryptBlock) != 0) { // 余數(shù)非0,block數(shù)再加1
nBlock += 1;
}
// 輸出buffer, 大小為nBlock個(gè)decryptBlock
ByteArrayOutputStream outbuf = new ByteArrayOutputStream(nBlock * decryptBlock);
cipher.init(Cipher.ENCRYPT_MODE, peerPubKey);
// 分段加密
for (int offset = 0; offset < plainBytes.length; offset += encryptBlock) {
// block大小: encryptBlock 或 剩余字節(jié)數(shù)
int inputLen = (plainBytes.length – offset);
if (inputLen > encryptBlock) {
inputLen = encryptBlock;
}
// 得到分段加密結(jié)果
byte[] encryptedBlock = cipher.doFinal(plainBytes, offset, inputLen);
// 追加結(jié)果到輸出buffer中
outbuf.write(encryptedBlock);
}
// 如果是Base64編碼,則返回Base64編碼后的數(shù)組
if (useBase64Code) {
return Base64.encodeBase64String(outbuf.toByteArray()).getBytes(
charset);
} else {
return outbuf.toByteArray(); // ciphertext
}
}
4. 報(bào)文明文+商戶的私鑰非對稱加密得到報(bào)文數(shù)字簽名sign。
/**
* RSA簽名
*
* @return byte[]
* @throws Exception
*/
public byte[] signRSA(byte[] plainBytes, boolean useBase64Code, String charset) throws Exception {
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initSign(localPrivKey);
signature.update(plainBytes);
// 如果是Base64編碼的話,需要對簽名后的數(shù)組以Base64編碼
if (useBase64Code) {
return Base64.encodeBase64String(signature.sign()).getBytes(charset);
} else {
return signature.sign();
}
}
5. 加密后的會話密鑰key+銀行的私鑰解密得到會話密鑰明文desKey;對稱加密得到的密文message+會話密鑰明文desKey解密得到報(bào)文明文
/**
* RSA解密
*
* @param cryptedBytes
* 待解密信息
* @return byte[]
* @throws Exception
*/
public byte[] decryptRSA(byte[] cryptedBytes, boolean useBase64Code,
String charset) throws Exception {
String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding"; // 加密block需要預(yù)留11字節(jié)
byte[] data = null;
// 如果是Base64編碼的話,則要Base64解碼
if (useBase64Code) {
data = Base64.decodeBase64(new String(cryptedBytes, charset));
} else {
data = cryptedBytes;
}
int KEYBIT = 2048;
int RESERVEBYTES = 11;
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
int decryptBlock = KEYBIT / 8; // 256 bytes
int encryptBlock = decryptBlock – RESERVEBYTES; // 245 bytes
// 計(jì)算分段解密的block數(shù) (理論上應(yīng)該能整除)
int nBlock = (data.length / decryptBlock);
// 輸出buffer, , 大小為nBlock個(gè)encryptBlock
ByteArrayOutputStream outbuf = new ByteArrayOutputStream(nBlock * encryptBlock);
cipher.init(Cipher.DECRYPT_MODE, localPrivKey);
// 分段解密
for (int offset = 0; offset < data.length; offset += decryptBlock) {
// block大小: decryptBlock 或 剩余字節(jié)數(shù)
int inputLen = (data.length – offset);
if (inputLen > decryptBlock) {
inputLen = decryptBlock;
}
// 得到分段解密結(jié)果
byte[] decryptedBlock = cipher.doFinal(data, offset, inputLen);
// 追加結(jié)果到輸出buffer中
outbuf.write(decryptedBlock);
}
outbuf.flush();
outbuf.close();
return outbuf.toByteArray();
}
6. 得到的明文+商戶的公鑰驗(yàn)簽,得到報(bào)文是否被中途篡改過
public boolean verifyRSA(byte[] plainBytes, byte[] signBytes,
boolean useBase64Code, String charset) throws Exception {
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initVerify(peerPubKey);
signature.update(plainBytes);
// 如果是Base64編碼的話,需要對驗(yàn)簽的數(shù)組以Base64解碼
if (useBase64Code) {
return signature.verify(Base64.decodeBase64(new String(signBytes, charset)));
} else {
return signature.verify(signBytes);
}
}
代碼只給出了一部分重要的加解密,加驗(yàn)簽邏輯。還有一些邏輯都貼出來有點(diǎn)亂,就放在倉庫里了,具體用法查看README即可,[更詳細(xì)的參考放在demo里](https://gitee.com/metaboli**/decry_eencrypt_mock)
### 思考:為什么RSA公鑰加密的值一定只有私鑰才能解開,不能暴力破解??
其實(shí)RSA的原理很簡單,運(yùn)用了數(shù)學(xué)的一個(gè)難題:兩個(gè)大的質(zhì)數(shù)相乘,難以在短時(shí)間內(nèi)將其因式分解。原理很簡單,但實(shí)際上**作真的很難。
##### 時(shí)間復(fù)雜度–O
我們都知道計(jì)算機(jī)的計(jì)算速度非常快,計(jì)算幾十位數(shù)的加減法都是秒出。
然而,雖然計(jì)算機(jī)很快,但再快也是有上限的。
比如我電腦的CPU主頻是2.30GHz,也就是說我的電腦每秒可以進(jìn)行2300000000次最基本的運(yùn)行。
![](https://image-static.segmentfault.com/121/362/1213624279-5dd4d4d083d21_articlex)
計(jì)算機(jī)的計(jì)算能力有限,就算是超級計(jì)算機(jī)“天河二號”,每秒也只能算3.39億億(這里多了個(gè)億 ,給大佬跪了orz)次。
對應(yīng)的,我們有一個(gè)參數(shù)來衡量一個(gè)程序的耗時(shí),叫做時(shí)間復(fù)雜度:
| 多項(xiàng)式量級 | 不嚴(yán)格的通俗例子(輸入規(guī)模![[公式]](https://www.zhihu.com/equation?tex=n%3D10%5E9)) |
| ———————————————————— | ———————————————————— |
| 常量階 ![O(1)](https://math.jianshu.com/math?formula=O(1)) | 只用1次運(yùn)算,普通電腦 ![[公式]](https://www.zhihu.com/equation?tex=10%5E%7B-9%7D) 秒就能算完。 |
| 對數(shù)階 ![O(log{n})](https://math.jianshu.com/math?formula=O(%5Clog%7Bn%7D)) | 大約會用30次計(jì)算,普通電腦 ![[公式]](https://www.zhihu.com/equation?tex=10%5E%7B-8%7D) 秒算完 |
| 線性階 ![O(n)](https://math.jianshu.com/math?formula=O(n)) | ![[公式]](https://www.zhihu.com/equation?tex=10%5E9) 次計(jì)算,普通電腦需要一秒左右 |
| 線性對數(shù)階 ![O(n log n)](https://math.jianshu.com/math?formula=O(n%20log%20n)) | |
| 平方階 ![O(n^{2})](https://math.jianshu.com/math?formula=O(n%5E%7B2%7D)),立方階 ![O(n^{3})](https://math.jianshu.com/math?formula=O(n%5E%7B3%7D)) | 大約是 ![[公式]](https://www.zhihu.com/equation?tex=10%5E%7B18%7D) 次計(jì)算,普通電腦大概要30年。 |
| 非多項(xiàng)式量級 | 不嚴(yán)格的通俗例子(輸入規(guī)模![[公式]](https://www.zhihu.com/equation?tex=n%3D10%5E9)) |
| ———————————————————— | ———————————————————— |
| 指數(shù)階 ![2^{n}](https://math.jianshu.com/math?formula=2%5E%7Bn%7D) | 大約2^1000000000次計(jì)算,心態(tài)崩了 |
| 階乘階 n! | 人類所有電腦加在一起,等太陽炸了都算不完 |
算法復(fù)雜度有各種各樣的,有 ![[公式]](https://www.zhihu.com/equation?tex=O%281%29) , ![[公式]](https://www.zhihu.com/equation?tex=O%28logn%29), ![[公式]](https://www.zhihu.com/equation?tex=O%28n%29), ![[公式]](https://www.zhihu.com/equation?tex=O%28n%5E2%29), ![[公式]](https://www.zhihu.com/equation?tex=O%282%5En%29)……上述幾個(gè)復(fù)雜度的算法一個(gè)比一個(gè)慢。通俗的講,大O后面括號里面**函數(shù)的增長速度越快,算法越耗時(shí)**。
總的來說,RSA之所以理論上非常安全,是因?yàn)槠平釸SA所要付出地計(jì)算成本遠(yuǎn)遠(yuǎn)高于使用RSA進(jìn)行加密的計(jì)算成本。
* 使用RSA的私鑰進(jìn)行解密,耗用的時(shí)間復(fù)雜度是**多項(xiàng)式級**。
* 不使用RSA私鑰,暴力破解,需要分解質(zhì)因數(shù),他的時(shí)間復(fù)雜度是**非多項(xiàng)式級**的**指數(shù)級**。
* 也就是有私鑰解密只要一秒,暴力破解出結(jié)果時(shí),人類可能已經(jīng)毀滅了(不嚴(yán)格)。
##### RSA生成公私鑰數(shù)學(xué)計(jì)算流程:
1. 商戶隨機(jī)生成了一些非常非常大的整數(shù),并用Miller-Rabin算法檢測它們是不是質(zhì)數(shù),直到找到兩個(gè)大質(zhì)數(shù)——![[公式]](https://www.zhihu.com/equation?tex=p_1) 和 ![[公式]](https://www.zhihu.com/equation?tex=p_2) 。(隨機(jī)數(shù)生成:多項(xiàng)式時(shí)間;Miller-Rabin: 多項(xiàng)式時(shí)間)
2. 商戶計(jì)算兩個(gè)質(zhì)數(shù)的乘積 ![[公式]](https://www.zhihu.com/equation?tex=n%3Dp_1p_2) (乘法: 多項(xiàng)式時(shí)間)
3. 商戶計(jì)算 φ(n) = (p1 – 1)(p2 – 1) (乘法: 多項(xiàng)式時(shí)間),這一步難以被破解,因?yàn)閚太大了,分解質(zhì)因數(shù)需要指數(shù)級時(shí)間復(fù)雜度。人類毀滅前是根據(jù)n推算出φ(n)可能性極小。
* **歐拉函數(shù):φ(n)表示:小于n的正整數(shù)中與n互質(zhì)的數(shù)的數(shù)目。**(互質(zhì)表示公因數(shù)為1)
比如想要知道φ(10)的話,我們就可以看[1, 10)中和10互質(zhì)的整數(shù),也就是1、3、7、9這四個(gè)數(shù)。(2、4、6、8和10有公因數(shù)2,而5和10有公因數(shù)10)。所以φ(10)=4。
比如想要知道φ(21)的話,我們就可以看[1, 21)中和21互質(zhì)的整數(shù),也就是1、2、4、5、8、10、11、13、16、17、19、20這12個(gè)數(shù)。(3、6、9、12、15、18和21有公因數(shù)3,而7、14和21有公因數(shù)7)。所以φ(21)=12。
4. 商戶構(gòu)造了一個(gè)比1大、比φ(n)小、不等于 ![[公式]](https://www.zhihu.com/equation?tex=p_1) 或 ![[公式]](https://www.zhihu.com/equation?tex=p_2) 的整數(shù)e。(隨機(jī)數(shù):多項(xiàng)式時(shí)間)
5. 商戶求出了e對于φ(n)的乘法逆元d,也就是說**ed ≡ 1(mod φ(n))**,也就是說ed=kφ(n)+1 (擴(kuò)展歐幾里得,多項(xiàng)式時(shí)間)
6. **請注意!現(xiàn)在神奇的事情發(fā)生了!對于一個(gè)與n互質(zhì)的數(shù)a:**
因?yàn)?![[公式]](https://www.zhihu.com/equation?tex=a%5E%7B%CF%86%28n%29%7D%E2%89%A11+) (mod n)
所以 ![[公式]](https://www.zhihu.com/equation?tex=a%5E%7Bk%CF%86%28n%29%7D%E2%89%A11) (mod n)
所以 ![[公式]](https://www.zhihu.com/equation?tex=a%5E%7Bk%CF%86%28n%29%2B1%7D%E2%89%A1a) (mod n)
所以 ![[公式]](https://www.zhihu.com/equation?tex=a%5E%7Bed%7D%E2%89%A1a) (mod n)
所以,若 ![[公式]](https://www.zhihu.com/equation?tex=c%5Cequiv+a%5Ee) (mod n), 則![[公式]](https://www.zhihu.com/equation?tex=c%5Ed%5Cequiv+a%5E%7Bed%7D+%5Cequiv+a)(mod n)
**到這里,兩把鑰匙構(gòu)造完成!ㄟ(≧◇≦)ㄏ**
**公鑰:(n, e)**
**密鑰:(n, d)**
##### RSA公私鑰加密解密
商戶想要生成一對公私鑰的時(shí)候:
* 第一隨意選擇兩個(gè)大的質(zhì)數(shù)p和q,p不等于q,計(jì)算N=pq。
* 根據(jù)歐拉函數(shù),求得r = (p-1)(q-1)
* 選擇一個(gè)小于 r 的整數(shù) e,求得 e 關(guān)于模 r 的模反元素,命名為d。(模反元素存在,當(dāng)且僅當(dāng)e與r互質(zhì))
* 將 p 和 q 的記錄銷毀。
* (N,e)是公鑰,(N,d)是私鑰。商戶將她的公鑰(N,e)傳給銀行,而將自己的私鑰(N,d)藏起來。
商戶進(jìn)行加密的時(shí)候:
* 假設(shè)商戶想給銀行送一個(gè)消息m,他知道銀行的公鑰,換句話說是銀行公鑰的N和e。他使用起先與銀行約好的格式將m轉(zhuǎn)換為一個(gè)小于N的整數(shù)n,比如他可以將每一個(gè)字轉(zhuǎn)換為這個(gè)字的Unicode碼,第二將這些數(shù)字連在一起組成一個(gè)數(shù)字。假如他的信息非常長的話,他可以將這個(gè)信息分為幾段,第二將每一段轉(zhuǎn)換為n。用下面這個(gè)公式他可以將n加密為c:
? ne ≡ c (mod N)
計(jì)算c并不復(fù)雜。商戶算出c后就可以將它傳遞給銀行,也就是密文啦。
銀行想要解密的時(shí)候:
* 銀行得到商戶的密文消息c(商戶使用銀行公鑰加密后的密文)后就可以利用他的私鑰d來解碼。他可以用以下這個(gè)公式來將c轉(zhuǎn)換為n:
cd ≡ n (mod N)
得到n后,他可以將原來的信息m重新復(fù)原。
### 其他的概念
##### 素?cái)?shù)
素?cái)?shù)又稱質(zhì)數(shù),指在一個(gè)大于1的自然數(shù)中,除了1和此整數(shù)自身外,不能被其他自然數(shù)整除的數(shù)
##### 互質(zhì)數(shù)
互質(zhì),又稱互素。若N個(gè)整數(shù)的最大公因子是1,則稱這N個(gè)整數(shù)互質(zhì)。
##### 指數(shù)運(yùn)算
指數(shù)運(yùn)算又稱乘方計(jì)算,計(jì)算結(jié)果稱為冪。nm指將n自乘m次。把nm看作乘方的結(jié)果,叫做”n的m次冪”或”n的m次方”。其中,n稱為“底數(shù)”,m稱為“指數(shù)”。
##### 模運(yùn)算
模運(yùn)算即求余運(yùn)算。
##### 同余
當(dāng)兩個(gè)整數(shù)除以同一個(gè)正整數(shù),若得相同余數(shù),則二整數(shù)同余。
##### 會話密鑰
前提:對稱加密速度要比非對稱加密快速。會話密鑰是一個(gè)隨機(jī)生成的對稱式加密密鑰,舉個(gè)例子:A和B交互,A隨機(jī)挑了一個(gè)字符串,用B的公鑰加密發(fā)給了B,告訴B這個(gè)隨機(jī)字符串就是他們之間用來交流的密鑰了,之后A和B的報(bào)文就可以不用公私鑰非對稱加密,直接用這個(gè)密鑰對稱加密即可。對稱式加密算法有很多:AES/DES等。SSH通信的數(shù)據(jù)就是用AES之類的對稱式加密算法加密的。(在SSH協(xié)商密鑰的過程中,還會使用專門的**密鑰協(xié)商算法(Key Exchange Algorithm)**,確保**者無法偷聽到密鑰的內(nèi)容)
##### 中間人攻擊
即當(dāng)商戶發(fā)送公鑰給銀行的時(shí)候,黑客截取了商戶的公鑰,同時(shí)把自己公鑰發(fā)給銀行,這樣一直在與銀行通信的并不是商戶。
##### CA認(rèn)證中心
專門提供網(wǎng)絡(luò)身份認(rèn)證服務(wù)的機(jī)構(gòu)或團(tuán)體
### 小編綜合來說
數(shù)學(xué)的魅力在于將這個(gè)世界變得井井有條,試想當(dāng)計(jì)算機(jī)的運(yùn)行速度越來越快,RSA會被破解嗎?不見得,1999年N(兩個(gè)大質(zhì)數(shù)的乘積)位數(shù)是512,后面發(fā)展成了位數(shù)是1024和2048位,計(jì)算機(jī)速度變快之后,每臺電腦能處理的位數(shù)也會越來越大,我相信我們會見到更長位數(shù)的N,十萬,甚至百萬….
浩瀚世界,自己真渺小
拓展知識:
photoshopcs5破解方
第一步:下載 Photoshop CS5 簡體中文版 丁
第二步:以試用方式安裝 Adobe Photoshop CS5,不需要輸入序列號
第三步:修改C:\Windows\System32\drivers\etc路徑下的hosts文件,否則序列號在下次啟動時(shí)會無效。將下面的內(nèi)容附加的該文件的 后面并保存:
127.0.0.1 activate.adobe.com
127.0.0.1 practivate.adobe.com
127.0.0.1 ereg.adobe.com
127.0.0.1 activate.wip3.adobe.com
127.0.0.1 wip3.adobe.com
127.0.0.1 3dns-3.adobe.com
127.0.0.1 3dns-2.adobe.com
127.0.0.1 adobe-dns.adobe.com
127.0.0.1 adobe-dns-2.adobe.com
127.0.0.1 adobe-dns-3.adobe.com
127.0.0.1 ereg.wip3.adobe.com
127.0.0.1 activate-sea.adobe.com
127.0.0.1 wwis-dubc1-vip60.adobe.com
127.0.0.1 activate-sjc0.adobe.com
打開軟件PS 輸入序列號(使用注冊機(jī))提示進(jìn)入下一步。
photoshopcs5破解方
第一步:下載 Photoshop CS5 簡體中文版 丁
第二步:以試用方式安裝 Adobe Photoshop CS5,不需要輸入序列號
第三步:修改C:\Windows\System32\drivers\etc路徑下的hosts文件,否則序列號在下次啟動時(shí)會無效。將下面的內(nèi)容附加的該文件的 后面并保存:
127.0.0.1 activate.adobe.com
127.0.0.1 practivate.adobe.com
127.0.0.1 ereg.adobe.com
127.0.0.1 activate.wip3.adobe.com
127.0.0.1 wip3.adobe.com
127.0.0.1 3dns-3.adobe.com
127.0.0.1 3dns-2.adobe.com
127.0.0.1 adobe-dns.adobe.com
127.0.0.1 adobe-dns-2.adobe.com
127.0.0.1 adobe-dns-3.adobe.com
127.0.0.1 ereg.wip3.adobe.com
127.0.0.1 activate-sea.adobe.com
127.0.0.1 wwis-dubc1-vip60.adobe.com
127.0.0.1 activate-sjc0.adobe.com
打開軟件PS 輸入序列號(使用注冊機(jī))提示進(jìn)入下一步。
原創(chuàng)文章,作者:九賢生活小編,如若轉(zhuǎn)載,請注明出處:http://m.xiesong.cn/47303.html