版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2017.08.20 |
前言
在這個(gè)信息爆炸的年代缤苫,特別是一些敏感的行業(yè),比如金融業(yè)和銀行卡相關(guān)等等驼鹅,這都對(duì)
app
的安全機(jī)制有更高的需求,很多大公司都有安全 部門森篷,用于檢測自己產(chǎn)品的安全性输钩,但是及時(shí)是這樣,安全問題仍然被不斷曝出仲智,接下來幾篇我們主要說一下app
的安全機(jī)制买乃。感興趣的看我上面幾篇。
1. APP安全機(jī)制(一)—— 幾種和安全性有關(guān)的情況
2. APP安全機(jī)制(二)—— 使用Reveal查看任意APP的UI
3. APP安全機(jī)制(三)—— Base64加密
4. APP安全機(jī)制(四)—— MD5加密
5. APP安全機(jī)制(五)—— 對(duì)稱加密
6. APP安全機(jī)制(六)—— 非對(duì)稱加密
SHA算法基本了解
下面我們先對(duì)SHA算法進(jìn)行簡單的了解钓辆,以下部分內(nèi)容來自百度百科剪验。
SHA基本了解
SHA
也可以稱為安全哈希算法或者安全散列算法。
安全哈希算法(Secure Hash Algorithm)
主要適用于數(shù)字簽名標(biāo)準(zhǔn)(Digital Signature Standard DSS)
里面定義的數(shù)字簽名算法(Digital Signature Algorithm DSA)
前联。對(duì)于長度小于2^64位的消息功戚,SHA1會(huì)產(chǎn)生一個(gè)160位的消息摘要。該算法經(jīng)過加密專家多年來的發(fā)展和改進(jìn)已日益完善似嗤,并被廣泛使用啸臀。該算法的思想是接收一段明文,然后以一種不可逆的方式將它轉(zhuǎn)換成一段(通常更兴嘎洹)密文乘粒,也可以簡單的理解為取一串輸入碼(稱為預(yù)映射或信息)豌注,并把它們轉(zhuǎn)化為長度較短、位數(shù)固定的輸出序列即散列值(也稱為信息摘要或信息認(rèn)證代碼)的過程灯萍。散列函數(shù)值可以說是對(duì)明文的一種“指紋”或是“摘要”所以對(duì)散列值的數(shù)字簽名就可以視為對(duì)此明文的數(shù)字簽名轧铁。
SHA是美國國家標(biāo)準(zhǔn)技術(shù)研究所發(fā)布的國家標(biāo)準(zhǔn)FIPS PUB 180
,最新的標(biāo)準(zhǔn)已經(jīng)于2008年更新到FIPS PUB 180-3
旦棉。其中規(guī)定了SHA-1齿风,SHA-224,SHA-256绑洛,SHA-384救斑,SHA-512
這幾種單向散列算法。SHA-1诊笤,SHA-224和SHA-256適用于長度不超過2^64
二進(jìn)制位的消息系谐。SHA-384和SHA-512適用于長度不超過2^128
二進(jìn)制位的消息巾陕。
下面我們看一下SHA算法目前的家族成員讨跟。
散列算法
散列是信息的提煉,通常其長度要比信息小得多鄙煤,且為一個(gè)固定長度晾匠。加密性強(qiáng)的散列一定是不可逆的,這就意味著通過散列結(jié)果梯刚,無法推出任何部分的原始信息凉馆。任何輸入信息的變化,哪怕僅一位亡资,都將導(dǎo)致散列結(jié)果的明顯變化澜共,這稱之為雪崩效應(yīng)。散列還應(yīng)該是防沖突的锥腻,即找不出具有相同散列結(jié)果的兩條信息嗦董。具有這些特性的散列結(jié)果就可以用于驗(yàn)證信息是否被修改。
單向散列函數(shù)一般用于產(chǎn)生消息摘要瘦黑,密鑰加密等京革,常見的有:
-
MD5(Message Digest Algorithm 5)
:是RSA數(shù)據(jù)安全公司開發(fā)的一種單向散列算法。 -
SHA(Secure Hash Algorithm)
:可以對(duì)任意長度的數(shù)據(jù)運(yùn)算生成一個(gè)160位的數(shù)值幸斥。
在1993年匹摇,安全散列算法(SHA)由美國國家標(biāo)準(zhǔn)和技術(shù)協(xié)會(huì)(NIST)提出,并作為聯(lián)邦信息處理標(biāo)準(zhǔn)(FIPS PUB 180)
公布甲葬;1995年又發(fā)布了一個(gè)修訂版FIPS PUB 180-1
廊勃,通常稱之為SHA-1。SHA-1是基于MD4算法的经窖,并且它的設(shè)計(jì)在很大程度上是模仿MD4的」┎螅現(xiàn)在已成為公認(rèn)的最安全的散列算法之一隅居,并被廣泛使用。
SHA算法基本原理
下面我們就看一下SHA算法的基本原理葛虐。
SHA-1是一種數(shù)據(jù)加密算法胎源,該算法的思想是接收一段明文,然后以一種不可逆的方式將它轉(zhuǎn)換成一段(通常更杏炱辍)密文涕蚤,也可以簡單的理解為取一串輸入碼(稱為預(yù)映射或信息),并把它們轉(zhuǎn)化為長度較短的诵、位數(shù)固定的輸出序列即散列值(也稱為信息摘要或信息認(rèn)證代碼)的過程万栅。
單向散列函數(shù)的安全性在于其產(chǎn)生散列值的操作過程具有較強(qiáng)的單向性。如果在輸入序列中嵌入密碼西疤,那么任何人在不知道密碼的情況下都不能產(chǎn)生正確的散列值烦粒,從而保證了其安全性。SHA將輸入流按照每塊512位(64個(gè)字節(jié))進(jìn)行分塊代赁,并產(chǎn)生20個(gè)字節(jié)的被稱為信息認(rèn)證代碼或信息摘要的輸出扰她。
該算法輸入報(bào)文的長度不限,產(chǎn)生的輸出是一個(gè)160位的報(bào)文摘要芭碍。輸入是按512 位的分組進(jìn)行處理的徒役。SHA-1是不可逆的、防沖突窖壕,并具有良好的雪崩效應(yīng)忧勿。
通過散列算法可實(shí)現(xiàn)數(shù)字簽名實(shí)現(xiàn),數(shù)字簽名的原理是將要傳送的明文通過一種函數(shù)運(yùn)算(Hash)轉(zhuǎn)換成報(bào)文摘要(不同的明文對(duì)應(yīng)不同的報(bào)文摘要)瞻讽,報(bào)文摘要加密后與明文一起傳送給接受方鸳吸,接受方將接受的明文產(chǎn)生新的報(bào)文摘要與發(fā)送方的發(fā)來報(bào)文摘要解密比較,比較結(jié)果一致表示明文未被改動(dòng)速勇,如果不一致表示明文已被篡改晌砾。
MAC
(信息認(rèn)證代碼)就是一個(gè)散列結(jié)果,其中部分輸入信息是密碼快集,只有知道這個(gè)密碼的參與者才能再次計(jì)算和驗(yàn)證MAC碼的合法性贡羔。
SHA-1與MD5的比較
因?yàn)槎呔蒑D4導(dǎo)出,都是不可逆的个初,SHA-1和MD5彼此很相似乖寒,都是把輸入二進(jìn)制串分成512位的塊,把二進(jìn)制串的位數(shù)存儲(chǔ)在最后64位院溺,二者之間填充為0楣嘁,依次對(duì)每個(gè)塊進(jìn)行一些列高深的數(shù)學(xué)運(yùn)算,最后得到一個(gè)160位的二進(jìn)制串。相應(yīng)的逐虚,他們的強(qiáng)度和其他特性也是相似聋溜,但還有以下幾點(diǎn)不同:
- 對(duì)強(qiáng)行攻擊的安全性:最顯著和最重要的區(qū)別是SHA-1摘要比MD5摘要長32 位。使用強(qiáng)行技術(shù)叭爱,產(chǎn)生任何一個(gè)報(bào)文使其摘要等于給定報(bào)摘要的難度對(duì)MD5是2128數(shù)量級(jí)的操作撮躁,而對(duì)SHA-1則是2160數(shù)量級(jí)的操作。這樣买雾,SHA-1對(duì)強(qiáng)行攻擊有更大的強(qiáng)度把曼。
- 對(duì)密碼分析的安全性:由于MD5的設(shè)計(jì),易受密碼分析的攻擊漓穿,SHA-1顯得不易受這樣的攻擊嗤军。
- 速度:在相同的硬件上,SHA-1的運(yùn)行速度比MD5慢晃危。
SHA-1停止計(jì)劃
2005年叙赚,密碼學(xué)家就證明SHA-1的破解速度比預(yù)期提高了2000倍,雖然破解仍然是極其困難和昂貴的僚饭,但隨著計(jì)算機(jī)變得越來越快和越來越廉價(jià)震叮,SHA-1算法的安全性也逐年降低,已被密碼學(xué)家嚴(yán)重質(zhì)疑浪慌,希望由安全強(qiáng)度更高的SHA-2替代它冤荆。
微軟第一個(gè)宣布了SHA-1棄用計(jì)劃朴则,對(duì)于SSL證書和代碼簽名證書权纤,微軟設(shè)定了不同的替換時(shí)間表。
- 所有Windows受信任的根證書頒發(fā)機(jī)構(gòu)(CA)從2016年1月1日起必須停止簽發(fā)新的SHA-1簽名算法SSL證書和代碼簽名證書乌妒;
- 對(duì)于SSL證書汹想,Windows將于2017年1月1日起停止支持SHA1證書。也就是說:任何在之前簽發(fā)的SHA-1證書必須替換成SHA-2證書撤蚊;
- 對(duì)于代碼簽名證書古掏,Windows將于2016年1月1日停止接受沒有時(shí)間戳的SHA-1簽名的代碼和SHA-1證書。也就是說侦啸,Windows仍然接受在2016年1月1日之前使用SHA-1簽名的已經(jīng)加上RFC3161時(shí)間戳的代碼槽唾,直到微軟認(rèn)為有可能出現(xiàn)SHA-1攻擊時(shí)。
SHA加密應(yīng)用領(lǐng)域
計(jì)算MD5或sha-1加密哈希值的文件
當(dāng)您將哈希算法應(yīng)用于任意數(shù)量的如一個(gè)二進(jìn)制文件的數(shù)據(jù)時(shí)結(jié)果將是一個(gè)哈瞎馔浚或消息摘要庞萍。此哈希具有固定的大小。MD5 是創(chuàng)建一個(gè) 128 位的哈希值的哈希算法忘闻。sha-1 是創(chuàng)建一個(gè) 160 位哈希值的哈希算法钝计。
文件校驗(yàn)和完整性驗(yàn)證程序(Microsoft File Checksum Integrity Verifier,簡寫為FCIV)
實(shí)用程序可以用于計(jì)算 MD5
或 SHA-1
加密哈希值的文件。
SHA加密算法的工作過程
- 附加添湊位
對(duì)信息附加添湊位以便使它的長度等于448(模512)私恬。即使信息已經(jīng)達(dá)到需要的長度债沮,也總是附加添湊位。因此本鸣,添湊位的長度范圍是1至512位疫衩。添湊位由單個(gè)“1”后跟必要數(shù)目的“0”組成。
- 附加長度
將一個(gè)長64位的數(shù)據(jù)塊附加到信息添湊位后荣德,這個(gè)塊被視為一個(gè)無符號(hào)的64位整數(shù)隧土,而且包含了信息在附加添湊位之前的初始長度。
前面兩步的結(jié)果是產(chǎn)生長度為512的整數(shù)倍的信息命爬。用數(shù)字標(biāo)記信息擴(kuò)展后的512位分組序列Y0曹傀,Y1…YL-1
,于是擴(kuò)展后信息的總長度是LX512位饲宛。同樣地皆愉,結(jié)果是16個(gè)32位字的整數(shù)倍。讓M0艇抠,M1…MN-1
代表結(jié)果信息字幕庐,N為16的整數(shù)倍,因此N=LX16家淤。
- 初始化MD緩沖區(qū)
用一個(gè)160位的緩沖區(qū)存放哈希函數(shù)的中間結(jié)果和最終結(jié)果异剥。這個(gè)緩沖區(qū)用5個(gè)32位寄存器(A,B絮重,C冤寿,D,E)
表示青伤。這些寄存器初始化為如下的16進(jìn)制值(高8位在前):
A = 67452301
B = EFCDAB89
C = 98BADCFE
D = 10325476
E = C3D2E1FO
- 處理512位(16字)信息分組
SHA加密算法的核心是一個(gè)由80步處理組成的模塊督怜,請(qǐng)注意每一層(round)的輸入是當(dāng)前正處理的512位分組YQ和值為ABCDE的160位緩沖區(qū),并在每一層修改緩沖區(qū)的內(nèi)容狠角。再每一層中用到了一個(gè)輔助常數(shù)K1号杠,K1只用到4個(gè)不同的常數(shù)值》岣瑁總之姨蟋,對(duì)分組YQ,SHA加密算法以YQ和摘要的中間值MDQ作為輸入立帖。MDQ放在緩沖區(qū)ABCDE中眼溶,第80步的輸出與MDQ相加以產(chǎn)生MDQ+1。這個(gè)加法是利用模232加法厘惦,由緩沖區(qū)5個(gè)字中的每一個(gè)字單獨(dú)地與MDQ中相應(yīng)的字相加完成偷仿。
- 輸出
當(dāng)所有的L個(gè)512位分組處理完后哩簿,從L階段的輸出是160位的信息摘要。
SHA算法代碼實(shí)現(xiàn)
首先要注意的就是先要引入頭文件酝静。
#import <CommonCrypto/CommonDigest.h>
下面還是直接看代碼节榜。
1. JJSHAVC.m
#import "JJSHAVC.h"
#import <CommonCrypto/CommonDigest.h>
@interface JJSHAVC ()
@end
@implementation JJSHAVC
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor lightGrayColor];
//SHA1加密
NSString *sha1Result = [self sha1EncryptWithStr:@"Celin"];
NSLog(@"sha1Result = %@", sha1Result);
//SHA224加密
NSString *sha224Result = [self sha224EncryptWithStr:@"Celin"];
NSLog(@"sha224Result = %@", sha224Result);
//SHA256加密
NSString *sha256Result = [self sha256EncryptWithStr:@"Celin"];
NSLog(@"sha256Result = %@", sha256Result);
//SHA384加密
NSString *sha384Result = [self sha384EncryptWithStr:@"Celin"];
NSLog(@"sha384Result = %@", sha384Result);
//SHA512加密
NSString *sha512Result = [self sha512EncryptWithStr:@"Celin"];
NSLog(@"sha512Result = %@", sha512Result);
}
#pragma mark - Object Private Function
//SHA1加密
- (NSString *)sha1EncryptWithStr:(NSString *)str
{
const char *cstr = [str cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:str.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, (CC_LONG)data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
//SHA224加密
- (NSString *)sha224EncryptWithStr:(NSString *)str
{
const char *cstr = [str cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:str.length];
uint8_t digest[CC_SHA224_DIGEST_LENGTH];
CC_SHA224(data.bytes, (CC_LONG)data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA224_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA224_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
//SHA256加密
- (NSString *)sha256EncryptWithStr:(NSString *)str
{
const char *cstr = [str cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:str.length];
uint8_t digest[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(data.bytes, (CC_LONG)data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
//SHA384加密
- (NSString *)sha384EncryptWithStr:(NSString *)str
{
const char *cstr = [str cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:str.length];
uint8_t digest[CC_SHA384_DIGEST_LENGTH];
CC_SHA384(data.bytes, (CC_LONG)data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA384_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA384_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
//SHA512加密
- (NSString *)sha512EncryptWithStr:(NSString *)str
{
const char *cstr = [str cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:str.length];
uint8_t digest[CC_SHA512_DIGEST_LENGTH];
CC_SHA512(data.bytes, (CC_LONG)data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA512_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA512_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
@end
下面看輸出結(jié)果
2017-08-21 14:13:55.643371+0800 JJOC[10671:5089584] sha1Result = aed363e0fba9c78464db73d4194e5f20c3f15297
2017-08-21 14:13:55.643609+0800 JJOC[10671:5089584] sha224Result = 9b7b9632f22d940c9e078624d2accd8e25e485d05f2416d28f128d74
2017-08-21 14:13:55.643764+0800 JJOC[10671:5089584] sha256Result = 7cc6c461453b280c0385f184bcc4cde59da4f912fa3710b9a694426c5e0ac9d9
2017-08-21 14:13:55.643959+0800 JJOC[10671:5089584] sha384Result = bfd50fa8b70884477e09af76e032176c032b5f1265962cef65e9c7d38ab1abc2ee8e5f43f4452f465fecdf0986cfaa2f
2017-08-21 14:13:55.644370+0800 JJOC[10671:5089584] sha512Result = d6976712a0b6cc70b88324928196fa35135e911351e9c7d8deeee6ae00c59449b557d061125ef41abab72a2db38d3f9cf1b9ae852f47c8091856f254d321ca72
從上面這個(gè)輸出結(jié)果,大家可以看出SHA家族不同成員算法輸出位數(shù)也是不一樣的别智。MD5輸出128bit宗苍,SHA1
輸出160bit
,SHA256
輸出256bit
薄榛,另外還有SHA244
讳窟、SHA512
分別輸出244bit
,512bit
敞恋,其實(shí)從他們的名字上也可以看出來輸出的位數(shù)丽啡。
大家可以用網(wǎng)上的SHA算法加密工具進(jìn)行驗(yàn)證,我這里只驗(yàn)證SHA - 1的結(jié)果硬猫,下面看個(gè)圖示补箍。
參考文章
后記
未完,待續(xù)~~