1.對稱加密
- DES 數(shù)據(jù)加密標準(用得少,因為強度不夠)
- 3DES 使用3個密鑰,對相同的數(shù)據(jù)執(zhí)行3次加密,強度增強
- AES 高級密碼標準。
對稱加密:加解密用同樣一個Key
非對稱加密:RSA,公鑰,私鑰
HASH:不是加密算法
2.對稱加密應(yīng)用模式
- ECB(Electronic Code Book):電子密碼本模式。每一塊數(shù)據(jù),獨立加密。
最基本的加密模式,也就是通常理解的加密,相同的明文將永遠加密成相同的密文,無初始向量,容易受到密碼本重放攻擊,一般情況下很少用。
- CBC(Cipher Block Chaining):密碼分組鏈接模式。使用一個密鑰和一個初始化向量[IV]對數(shù)據(jù)執(zhí)行加密。
明文被加密前要與前面的密文進行異或運算后再加密,因此只要選擇不同的初始向量,相同的密文加密后會形成不同的密文,這是目前應(yīng)用最廣泛的模式。CBC加密后的密文是上下文相關(guān)的,但明文的錯誤不會傳遞到后續(xù)分組,但如果一個分組丟失,后面的分組將全部作廢(同步錯誤)。
CBC可以有效的保證密文的完整性,如果一個數(shù)據(jù)塊在傳遞是丟失或改變,后面的數(shù)據(jù)將無法正常解密。
ECB電子密碼本模式:每一塊數(shù)據(jù)單個數(shù)據(jù),獨立加密。abc.txt中用對稱加密之后,中間改第四行的數(shù)據(jù)再次加密,查看加密后的數(shù)據(jù),發(fā)現(xiàn)只有中間這一塊加密后的數(shù)據(jù)不同,其余沒有改動的位置加密結(jié)果數(shù)據(jù)完全相同
改動一個數(shù)字(第四行第一個數(shù)字改為8)是改動8個字節(jié),改動兩個數(shù)字(第四行第一二個數(shù)字改為8)是改動16個字節(jié),DES加密過程中最低是8個字節(jié)
CBC模式:傳入向量加密后,改了第四行的第一個數(shù)字,之后的加密結(jié)果均不一樣了,向量表示向某個方向運動的量,-iv自己確定向量的值,加解密同時需要-iv, 有幾何算法在里面,向量更加多變
key可以使字符,iv也可以是字符
openssl enc -des-cbc -K 616263 -iv 0102030405060708 -nosalt -in abc.txt -out msg3.bin
很多加密算法依賴幾何圖形,變量有規(guī)律,多變,幾何變量添加到加密算法后,破解難度更大
3.對稱加密算法代碼演練
代碼和終端加密效果一致
des和aes區(qū)別,des強度更小,aes-128-ecb中128代表強度128位,還有192,256位強度更大
解密,輸出解密后的結(jié)果,%為字符輸出有一個占位符,key在加密時用16進制表示
默認是AES,可以設(shè)置為DES
//默認是AES,設(shè)置為DES
[EncryptionTools sharedEncryptionTools].algorithm = kCCAlgorithmDES;
4.對稱加密源碼分析
- (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
// 設(shè)置秘鑰
NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
uint8_t cKey[self.keySize];
bzero(cKey, sizeof(cKey));
[keyData getBytes:cKey length:self.keySize];
// 設(shè)置iv
uint8_t cIv[self.blockSize];
bzero(cIv, self.blockSize);
int option = 0;
if (iv) {
[iv getBytes:cIv length:self.blockSize];
option = kCCOptionPKCS7Padding;
} else {
/**
kCCOptionPKCS7Padding | kCCOptionECBMode ECB 的模式
kCCOptionPKCS7Padding CBC 的加密
*/
option = kCCOptionPKCS7Padding | kCCOptionECBMode;
}
// 設(shè)置輸出緩沖區(qū)
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
size_t bufferSize = [data length] + self.blockSize;
void *buffer = malloc(bufferSize);
// 開始加密
size_t encryptedSize = 0;
//加密解密都是它 -- CCCrypt
/**
1.kCCEncrypt 加密/kCCDecrypt解密
2.加密算法
3.加密選項 ECB/CBC
4.KEY 的地址
5.KEY 的長度
6.iv 初始化向量
7.加密的數(shù)據(jù)(地址)
8.加密的數(shù)據(jù)長度
9.密文的內(nèi)存地址
10.密文緩沖區(qū)的大小
11.加密結(jié)果大小
*/
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
self.algorithm,
option,
cKey,
self.keySize,
cIv,
[data bytes],
[data length],
buffer,
bufferSize,
&encryptedSize);
NSData *result = nil;
//加密成功,緩沖區(qū)的結(jié)果拷貝出來
if (cryptStatus == kCCSuccess) {
result = [NSData dataWithBytesNoCopy:buffer length:encryptedSize];
} else {
//加密失敗,釋放緩沖區(qū),成功緩沖區(qū)不需要釋放,給它人調(diào)用使用
free(buffer);
NSLog(@"[錯誤] 加密失敗|狀態(tài)編碼: %d", cryptStatus);
}
//返回base64字符串
return [result base64EncodedStringWithOptions:0];
}
5.直接使用系統(tǒng)函數(shù)CCCrypt的安全問題
對CCCrypt下符號斷點
第七個參數(shù)是加密的數(shù)據(jù)地址,讀取寄存器中x6的值,讀取到了明文中的值,長度是5個字節(jié)
可以對明文String先進行一次按位異或,解密時對結(jié)果再次按位異或后return出去,防止系統(tǒng)函數(shù)被攔截讀取到加密前的明文
6.代碼簽名
代碼簽名是對可執(zhí)行文件或腳本進行數(shù)字簽名.用來確認軟件在簽名后未被修改或損壞的措施。和數(shù)字簽名原理一樣,只不過簽名的數(shù)據(jù)是代碼而已.
在iOS出來之前,以前的主流操作系統(tǒng)(Mac/Windows)軟件隨便從哪里下載都能運行,系統(tǒng)安全存在隱患,盜版軟件,病毒入侵,靜默安裝等等.那么蘋果希望解決這樣的問題,要保證每一個安裝到 iOS 上的 APP 都是經(jīng)過蘋果官方允許的,怎樣保證呢?就是通過代碼簽名。
如果要實現(xiàn)驗證.其實最簡單的方式就是通過蘋果官方生成非對稱加密的一對公私鑰.在iOS的系統(tǒng)中內(nèi)置一個公鑰,私鑰由蘋果后臺保存,我們傳APP到AppStore時,蘋果后臺用私鑰對APP數(shù)據(jù)進行簽名,iOS系統(tǒng)下載這個APP后,用公鑰驗證這個簽名,若簽名正確,這個APP肯定是由蘋果后臺認證的,并且沒有被修改過,也就達到了蘋果的需求:保證安裝的每一個APP都是經(jīng)過蘋果官方允許的.
如果我們iOS設(shè)備安裝APP只從App Store這一個入口這件事就簡單解決了,沒有任何復(fù)雜的東西,一個數(shù)字簽名搞定.
但是實際上iOS安裝APP還有其他渠道.比如對于我們開發(fā)者iOSER而言,我們是需要在開發(fā)APP時直接真機調(diào)試的.而且蘋果還開放了企業(yè)內(nèi)部分發(fā)的渠道,企業(yè)證書簽名的APP也是需要順利安裝的. 蘋果需要開放這些方式安裝APP,這些需求就無法通過簡單的代碼簽名來辦到了。
那么我們來分析一下,它有些什么需求:
安裝包不需要上傳到App Store,可以直接安裝到手機上.
蘋果為了保證系統(tǒng)的安全性,又必須對安裝的APP有絕對的控制權(quán)
經(jīng)過蘋果允許才可以安裝
不能被濫用導致非開發(fā)APP也能被安裝
為了實現(xiàn)這些需求,iOS簽名的復(fù)雜度也就開始增加了,蘋果這里給出的方案是雙層簽名.
iOS的雙層代碼簽名流程這里簡單梳理一下,這也不是最終的iOS簽名原理.iOS的最終簽名在這個基礎(chǔ)上還要稍微加點東西. 首先這里有兩個角色.一個是iOS系統(tǒng) 還有一個就是我們的Mac系統(tǒng).因為iOS的APP開發(fā)環(huán)境在Mac系統(tǒng)下.所以這個依賴關(guān)系成為了蘋果雙層簽名的基礎(chǔ).
在Mac系統(tǒng)中生成非對稱加密算法的一對公鑰\私鑰(你的Xcode幫你代辦了).這里稱為公鑰M 私鑰M . M = Mac
蘋果自己有固定的一對公私鑰,跟之前App Store原理一樣,私鑰在蘋果后臺,公鑰在每個iOS系統(tǒng)中.這里稱為公鑰A , 私鑰A. A=Apple
把公鑰M 以及一些你開發(fā)者的信息,傳到蘋果后臺(這個就是CSR文件),用蘋果后臺里的私鑰 A 去簽名公鑰M。得到一份數(shù)據(jù)包含了公鑰M 以及其簽名,把這份數(shù)據(jù)稱為證書。
在開發(fā)時,編譯完一個 APP 后,用本地的私鑰 M(今后你導出的P12) 對這個 APP 進行簽名,同時把第三步得到的證書一起打包進 APP 里,安裝到手機上。
在安裝時,iOS 系統(tǒng)取得證書,通過系統(tǒng)內(nèi)置的公鑰 A,去驗證證書的數(shù)字簽名是否正確。
驗證證書后確保了鑰 M 是蘋果認證過的,再用公鑰 M 去驗證 APP 的簽名,這里就間接驗證了這個 APP 安裝行為是否經(jīng)過蘋果官方允許。(這里只驗證安裝行為,不驗證APP 是否被改動,因為開發(fā)階段 APP 內(nèi)容總是不斷變化的,蘋果不需要管。)
有了上面的過程,已經(jīng)可以保證開發(fā)者的認證,和程序的安全性了。 但是,你要知道iOS的程序,主要渠道是要通過APP Store才能分發(fā)到用戶設(shè)備的,如果只有上述的過程,那豈不是只要申請了一個證書,就可以安裝到所有iOS設(shè)備了?
所有的簽名都會取哈希值,證書是整個進行加密,App的簽名將MachO的哈希值進行加密,公鑰解析哈希值和MachO本身的哈希值進行對比,私鑰A對公鑰M的加密不叫簽名,是進行加密生成證書
此過程保證了開發(fā)者開發(fā)App安裝到手機上是經(jīng)過認證的,但若只要申請了一個證書,任何設(shè)備都能安裝App了,那就不需要上傳AppStore了。
但事實上,蘋果的免費賬號對App數(shù)量是6個,期限是7天,證書過期,蘋果專門有了一個權(quán)限文件,即provision描述文件
7.描述文件
描述文件(Provisioning profile)一般包括三樣東西:證書、App ID、設(shè)備。當我們在真機運行或者打包一個項目的時候,證書用來證明我們程序的安全性和合法性。
蘋果為了解決應(yīng)用濫用的問題,所以蘋果又加了兩個限制.
第一限制在蘋果后臺注冊過的設(shè)備才可以安裝.
第二限制簽名只能針對某一個具體的APP.
并且蘋果還想控制App里面的iCloud/PUSH/后臺運行/調(diào)試器附加這些權(quán)限,所以蘋果把這些權(quán)限開關(guān)統(tǒng)一稱為Entitlements(授權(quán)文件).并將這個文件放在了一個叫做Provisioning Profile(描述文件)文件中.
描述文件是在AppleDevelop網(wǎng)站創(chuàng)建的(在Xcode中填上AppleID它會代辦創(chuàng)建),Xcode運行時會打包進入APP內(nèi).所以我們使用CSR申請證書時,我們還要申請一個東西!! 就是描述文件!
在開發(fā)時,編譯完一個 APP 后,用本地的私鑰M對這個APP進行簽名,同時把從蘋果服務(wù)器得到的 Provisioning Profile 文件打包進APP里,文件名為embedded.mobileprovision,把 APP 安裝到手機上.最后系統(tǒng)進行驗證。
1.證書:公鑰或私鑰發(fā)出去由官方的機構(gòu)對齊進行簽名,組成的數(shù)據(jù)包
2.p12:本地私鑰,可以導出到其他電腦上,給共同開發(fā)者使用
3.描述文件(各種權(quán)限):包含證書,權(quán)限文件Entitlements權(quán)限開關(guān),UUID等,描述文件無法擴充任何權(quán)限,需要去蘋果官方申請,有簽名驗證,沒有辦法修改它
描述文件存在App包里面,顯示包內(nèi)容能看到
查看描述文件信息,不可篡改,里面包含了UUID,是一個plist文件
若需要更多的權(quán)限只能去蘋果官方去申請,描述文件有驗證,最關(guān)鍵的文件,經(jīng)過簽名的,修改任何一點點東西就無效了
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AppIDName</key>
<string>XC com Logic -01--Demo123</string>
<key>ApplicationIdentifierPrefix</key>
<array>
<string>8ZSCVU88C4</string>
</array>
<key>CreationDate</key>
<date>2021-04-18T09:06:43Z</date>
<key>Platform</key>
<array>
<string>iOS</string>
</array>
<key>IsXcodeManaged</key>
<true/>
<key>DeveloperCertificates</key>
<array>
<data>MIIFsDCCBJigAwIBAgIIbCEYXeLlLuswDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMjAxMTMwMTI0NDI4WhcNMjExMTMwMTI0NDI4WjCBjjEaMBgGCgmSJomT8ixkAQEMCjU3UFFON1QzQ0MxOTA3BgNVBAMMMEFwcGxlIERldmVsb3BtZW50OiA3ODUxNDQxMzBAcXEuY29tIChMNjk0ODQ1UFZMKTETMBEGA1UECwwKOFpTQ1ZVODhDNDETMBEGA1UECgwK5qCL5LqRIOmEojELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7MPUDlWCWi+7lS9GzY7raojLpqNyC00xqzDNwM0LrlV8V89ShNBqfBaiPE6vybW+VGE/+c7jFDuThUVJB6n477MtSB2ZumPhXAt6lhBnJR+0h1G0IwkQwx4mDbD8S2wOSl4Ow24v0G7stSuN6iWxD2aU1YVo9ZP4if24tcDyg3adf0iVrLSD4Z1tgnwCzwWu7TukASEftE8CEChWcsfA02gozaZCg0LRFBQ+Z6O0sASEmfrTQzTFKXH6EUFZYgb8LmkysgCdx6/Lh6b4n7/n9CNJpRyXciIW+MwaY20veg8u1byBiq+mxp9gVOrKwSDouBNI5EPfouKrVUkh2NWY5AgMBAAGjggIGMIICAjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFIgnFwmpthhgi+zruvZHWcVSVKO3MD8GCCsGAQUFBwEBBDMwMTAvBggrBgEFBQcwAYYjaHR0cDovL29jc3AuYXBwbGUuY29tL29jc3AwMy13d2RyMTkwggEdBgNVHSAEggEUMIIBEDCCAQwGCSqGSIb3Y2QFATCB/jCBwwYIKwYBBQUHAgIwgbYMgbNSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2VydGlmaWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1lbnRzLjA2BggrBgEFBQcCARYqaHR0cDovL3d3dy5hcHBsZS5jb20vY2VydGlmaWNhdGVhdXRob3JpdHkvMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMB0GA1UdDgQWBBTSen1UhReEdPOaNqq3O/t8z9ZUJzAOBgNVHQ8BAf8EBAMCB4AwEwYKKoZIhvdjZAYBAgEB/wQCBQAwEwYKKoZIhvdjZAYBDAEB/wQCBQAwDQYJKoZIhvcNAQELBQADggEBAG3CCD92V2Fluqk7KvY12b5JcbceCrNGVcHDCro1lb1HyHm8Ejb9Cn58jJ4csnyIPRGrILI+uIpJxIRc/O9I5mXkOyxlEMNqCgKHCxMMMMM5L4f2NQSTNFLG0YSEde73nKAcqeAwWJOtlbBICdhXFZL1nW36ZM3h8E+bfeVqrZkQld7Goi9dmqS163g7zkc+pzNjA2YEfbAitseC4cnFmMbT/HLdLV/J058knHFD7OV4LJ7BaYfl+U684Bq0Z7YePvvx8wkhAmhGKqeW8ZLsi7/lsk10d5FeXUmuZjtlXNh54uY1LFbn9MGP3Lc+2lW30oe6NvOrfN00D/B5/x12JK8=</data>
</array>
<key>Entitlements</key>
<dict>
<key>application-identifier</key>
<string>8ZSCVU88C4.com.Logic.-01--Demo123</string>
<key>keychain-access-groups</key>
<array>
<string>8ZSCVU88C4.*</string>
</array>
<key>get-task-allow</key>
<true/>
<key>com.apple.developer.team-identifier</key>
<string>8ZSCVU88C4</string>
</dict>
<key>ExpirationDate</key>
<date>2021-04-25T09:06:43Z</date>
<key>Name</key>
<string>iOS Team Provisioning Profile: com.Logic.-01--Demo123</string>
<key>ProvisionedDevices</key>
<array>
<string>f2da39831ad63ca3429b8abad6d5f4cd5f40e937</string>
</array>
<key>LocalProvision</key>
<true/>
<key>TeamIdentifier</key>
<array>
<string>8ZSCVU88C4</string>
</array>
<key>TeamName</key>
<string>棟云 鄢</string>
<key>TimeToLive</key>
<integer>7</integer>
<key>UUID</key>
<string>f9d0420e-f18e-4380-8bd8-a53f93accd7e</string>
<key>Version</key>
<integer>1</integer>
</dict>
</plist>
8.證書生成流程
A.本地的公私鑰和csr文件去申請證書
B.蘋果服務(wù)器收到公鑰,進行RSA加密,生成證書返回
C.取得證書下載到本地,和本地私鑰M,也就是p12文件進行綁定,綁定后鑰匙串訪問能看到
D.安裝App時,用本地私鑰p12文件對應(yīng)用進行簽名驗證
包里面,資源文件的簽名在CodeResources
MachO文件的簽名信息在MachO文件中,通過MachOView可以查看到,若改變MachO的簽名信息,應(yīng)用就無法安裝,簽名信息數(shù)據(jù)大,通過RSA加密過,加密的是原始文件的哈希值,文件比較大后,哈希值也比較大了,一塊一塊的