對稱密鑰
對稱加密簡介
采用單鑰密碼系統(tǒng)的加密方法,同一個密鑰可以同時用作信息的加密和解密。這種加密方法稱為對稱加密,也稱為單密鑰加密。
對加密和解密使用相同密鑰的加密算法,其運算速度非常快,對稱加密通常在消息發(fā)送方需要加密大量數(shù)據(jù)時使用。
常用對稱加密算法
DES(Data Encryption Standard):數(shù)據(jù)加密標準,速度較快,適用于加密大量數(shù)據(jù)的場合;3DES(Triple DES):是基于DES,對一塊數(shù)據(jù)用三個不同的密鑰進行三次加密,其強度更高;AES(Advanced Encryption Standard):高級加密標準,是下一代的加密算法標準,速度快,安全級別高,支持128、192、256、512位密鑰的加密;
對稱加密算法特點:
- 加密方和解密方使用的是同一個密鑰
- 加密解密的速度比較快,適合數(shù)據(jù)量比較大的情況
- 密鑰傳輸?shù)倪^程不安全,且容易被破解,因此密鑰管理比較麻煩
應用模式:
ECB(Electronic Code Book):電子密碼本模式。它是最基本的加密模式,也是通常理解的加密,相同的明文將永遠加密成相同的密文,無初始向量,容易受到密碼本重放攻擊,一般情況下很少用。CBC(Cipher Block Chaining):密碼分組鏈接模式。明文被加密前要與前面的密文進行異或運算后再加密,因此只要選擇不同的初始微量,相同的密文加密后會形成不同的密文,這是目前應用最廣泛的模式。CBC加密后的密文是上下文相關(guān)的,但明文的錯誤不會傳遞到后續(xù)分組,如果一個分組丟失,后面的分組將全部作廢(同步錯誤)。CFB(Cipher Feedback Mode):加密反饋模式。類似于自同步序列密碼,分組加密后,按8位分組將密文和明文進行移位異或后得到輸出同時反饋回移位寄存器,優(yōu)點是最小可以按字節(jié)進行加解密,也可以是n位的。CFB也是上下文相關(guān)的,CFB模式下,明文的一個錯誤會影響后面的密文(錯誤擴散)OFB(Output Feedback Mode):輸出反饋模式。將分組密碼作為同步序列密碼運行,和CFB相似,不過OFB用的是前一個n們密文輸出分組反饋回移位寄存器,OFB沒有錯誤擴散問題。
對稱加密的優(yōu)缺點
優(yōu)點
對稱加密算法的優(yōu)點是:算法公開、計算量小、加密速度快、加密效率高。缺點
由于加解密使用同一密鑰,則密鑰的保存尤為重要,如果一方的密鑰被泄漏,那加密的信息也不安全。
終端演示對稱加密
- 使用DES加密,模式使用ECB
echo -n hello | openssl enc -des-ecb -K 616263 -nosalt | base64
//加密結(jié)果
HQr0Oij2kbo=
以下是對上述加密代碼的釋義:
-
echo -n hello:不換行的標準輸出 hello 字符串 -
openssl enc:使用openssl 進行數(shù)據(jù)加密,加密的數(shù)據(jù)就是 hello 字符串 -
-des-ecb:加密方式為 DES,加密模式為 ECB -
-K 616263:加密的密鑰為0x61 0x62 0x63(abc) -
-nosalt:openssl命令,默認隨機加鹽,通過-nosalt參數(shù),取消該策略 -
base64:由于加密后的數(shù)據(jù)是二進制的,通過base64使其顯示成可視字符串
- 使用DES解密,模式使用ECB
echo -n HQr0Oij2kbo= | base64 -D | openssl enc -d -des-ecb -K 616263 -nosalt
//解密結(jié)果:注意%為占位符,并不是原字符串內(nèi)容
hello%
釋義:
-
echo -n HQr0Oij2kbo= | base64 -D:由于前面加密后的數(shù)據(jù)是進行了base64編碼,因此首先需要做的是對字符串進行base64解碼。 -
openssl enc -d:表示當前操作是解密,-e表示加密操作,默認為加密操作 -
-des-ecb:加密方式為 DES,加密模式為 ECB -
-K 616263:加密的密鑰為0x61 0x62 0x63(abc) -
-nosalt:openssl命令,默認隨機加鹽,通過-nosalt參數(shù),取消該策略
- 使用DES加密,模式使用CBC
//加密 hello
echo -n hello | openssl enc -des-cbc -K 616263 -nosalt -iv 0102030405060708 | base64
//加密結(jié)果
alvrvb3Gz88=
- 使用DES解密,模式使用CBC
//解密 alvrvb3Gz88= 得到原字符串 hello
echo -n alvrvb3Gz88= | base64 -D | openssl enc -des-cbc -K 616263 -nosalt -iv 0102030405060708 -d
//解密結(jié)果
hello%
- 使用AES加密,模式使用ECB
//加密 hello
echo -n hello | openssl enc -aes-128-ecb -K 616263 -nosalt | base64
//加密結(jié)果
d1QG4T2tivoi0Kiu3NEmZQ==
- 使用AES解密,模式使用ECB
//解密 d1QG4T2tivoi0Kiu3NEmZQ== 得到結(jié)果 hello
echo -n d1QG4T2tivoi0Kiu3NEmZQ== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d
//解密結(jié)果
hello%
- 使用AES加密,模式使用CBC
//加密 hello
echo -n hello | openssl enc -aes-128-cbc -K 616263 -nosalt -iv 0102030405060708 | base64
//加密結(jié)果
u3W/N816uzFpcg6pZ+kbdg==
- 使用AES解密,模式使用CBC
//解密 u3W/N816uzFpcg6pZ+kbdg== 得到結(jié)果 hello
echo -n u3W/N816uzFpcg6pZ+kbdg== | base64 -D | openssl enc -aes-128-cbc -K 616263 -nosalt -iv 0102030405060708 -d
//解密結(jié)果
hello%
OC代碼演示對稱加密
封裝EncryptionTools加密庫,提供以下方法
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCrypto.h>
@interface EncryptionTools : NSObject
+ (instancetype)sharedEncryptionTools;
/**
@constant kCCAlgorithmAES 高級加密標準,128位(默認)
@constant kCCAlgorithmDES 數(shù)據(jù)加密標準
*/
@property (nonatomic, assign) uint32_t algorithm;
//加密字符串并返回base64編碼字符串
- (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;
//解密字符串
- (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;
@end
- DES加密,ECB模式
- (void)testDES_ECB:(NSString*)pwd andKey:(NSString*)key{
[EncryptionTools sharedEncryptionTools].algorithm = kCCAlgorithmDES;
NSString * encStr = [[EncryptionTools sharedEncryptionTools] encryptString:pwd keyString:key iv:nil];
NSLog(@"[DES_ECB]加密的結(jié)果是:%@",encStr);
NSLog(@"[DES_ECB]解密的結(jié)果是:%@",[[EncryptionTools sharedEncryptionTools] decryptString:encStr keyString:key iv:nil]);
}
//結(jié)果
2021-04-22 15:58:01.344155+0800 EncryptDemo[43690:24153812] [DES_ECB]加密的結(jié)果是:HQr0Oij2kbo=
2021-04-22 15:58:01.344437+0800 EncryptDemo[43690:24153812] [DES_ECB]解密的結(jié)果是:hello
- DES加密,CBC模式
- (void)testDES_CBC:(NSString*)pwd andKey:(NSString*)key andIv:(NSData*)iv{
[EncryptionTools sharedEncryptionTools].algorithm = kCCAlgorithmDES;
NSString * encStr = [[EncryptionTools sharedEncryptionTools] encryptString:pwd keyString:key iv:iv];
NSLog(@"[DES_CBC]加密的結(jié)果是:%@",encStr);
NSLog(@"[DES_CBC]解密的結(jié)果是:%@",[[EncryptionTools sharedEncryptionTools] decryptString:encStr keyString:key iv:iv]);
}
//結(jié)果
2021-04-22 15:58:01.344672+0800 EncryptDemo[43690:24153812] [DES_CBC]加密的結(jié)果是:alvrvb3Gz88=
2021-04-22 15:58:01.344877+0800 EncryptDemo[43690:24153812] [DES_CBC]解密的結(jié)果是:hello
- AES加密,ECB模式
- (void)testAES_ECB:(NSString*)pwd andKey:(NSString*)key{
[EncryptionTools sharedEncryptionTools].algorithm = kCCAlgorithmAES;
NSString * encStr = [[EncryptionTools sharedEncryptionTools] encryptString:pwd keyString:key iv:nil];
NSLog(@"[AES_ECB]加密的結(jié)果是:%@",encStr);
NSLog(@"[AES_ECB]解密的結(jié)果是:%@",[[EncryptionTools sharedEncryptionTools] decryptString:encStr keyString:key iv:nil]);
}
//結(jié)果
2021-04-22 15:58:01.345047+0800 EncryptDemo[43690:24153812] [AES_ECB]加密的結(jié)果是:d1QG4T2tivoi0Kiu3NEmZQ==
2021-04-22 15:58:01.345211+0800 EncryptDemo[43690:24153812] [AES_ECB]解密的結(jié)果是:hello
- AES加密,CBC模式
- (void)testAES_CBC:(NSString*)pwd andKey:(NSString*)key andIv:(NSData*)iv{
[EncryptionTools sharedEncryptionTools].algorithm = kCCAlgorithmAES;
NSString * encStr = [[EncryptionTools sharedEncryptionTools] encryptString:pwd keyString:key iv:iv];
NSLog(@"[AES_CBC]加密的結(jié)果是:%@",encStr);
NSLog(@"[AES_CBC]解密的結(jié)果是:%@",[[EncryptionTools sharedEncryptionTools] decryptString:encStr keyString:key iv:iv]);
}
//結(jié)果
2021-04-22 15:58:01.345395+0800 EncryptDemo[43690:24153812] [AES_CBC]加密的結(jié)果是:u3W/N816uzFpcg6pZ+kbdg==
2021-04-22 15:58:01.345557+0800 EncryptDemo[43690:24153812] [AES_CBC]解密的結(jié)果是:hello
CCCrypt函數(shù)
CCCrypt函數(shù)為系統(tǒng)提供的加解密函數(shù)。
CCCryptorStatus CCCrypt(
CCOperation op, /* kCCEncrypt, etc. */
CCAlgorithm alg, /* kCCAlgorithmAES128, etc. */
CCOptions options, /* kCCOptionPKCS7Padding, etc. */
const void *key,
size_t keyLength,
const void *iv, /* optional initialization vector */
const void *dataIn, /* optional per op and alg */
size_t dataInLength,
void *dataOut, /* data RETURNED here */
size_t dataOutAvailable,
size_t *dataOutMoved)
API_AVAILABLE(macos(10.4), iOS(2.0));
- 參數(shù)說明:
-
op:加解密標志。kCCEncrypt加密、kCCDecrypt解密 -
alg:加解密使用的算法標準 -
options:加密選項ECB/CBC -
key:key的內(nèi)存地址 -
keyLength:key的長度 -
iv:初始化向量,固定長度8字節(jié) -
dataIn:加密數(shù)據(jù)的內(nèi)存地址 -
dataInLength:加密的數(shù)據(jù)長度 -
dataOut:密文的內(nèi)存地址 -
dataOutAvailable:密文需要的可用空間大小,數(shù)據(jù)緩沖區(qū)的大?。ㄗ止?jié)) -
dataOutMoved:操作成功之后,被寫入dataOut的字節(jié)長度。如果由于提供的緩沖區(qū)空間不足而返回kCCBufferTooSmall,則在這里返回所需的緩沖區(qū)空間
-
- 加解密使用的算法標準
enum {
kCCAlgorithmAES128 = 0, /* Deprecated, name phased out due to ambiguity with key size */
kCCAlgorithmAES = 0,
kCCAlgorithmDES,
kCCAlgorithm3DES,
kCCAlgorithmCAST,
kCCAlgorithmRC4,
kCCAlgorithmRC2,
kCCAlgorithmBlowfish
};
- 初始化向量iv,在CBC模式下才需要
注意:CCCrypt函數(shù)為系統(tǒng)函數(shù),它可以通過符號斷點的方式,將其第七個參數(shù)截獲,從而破解出待加密的數(shù)據(jù),這是不安全的。
對稱算法簡單使用案例請前往Demo