加密整理


引言:

根據(jù)相關資料(上半部之哈希/下半部之對稱和非對稱加密)進行整理,方便以后回顧和查閱......

  1. Base64
  2. MD5、SHA1、SHA256、SHA512、HMAC
  3. AES
  4. RSA

一、Base64

1. 算法介紹

Base64是網(wǎng)絡上最常見的用于傳輸8Bit字節(jié)代碼的編碼方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的詳細規(guī)范。Base64編碼可用于在HTTP環(huán)境下傳遞較長的標識信息。個人感覺Base64僅僅是一種編碼方式(%02X)而不是加密方式如同UTF-8。
它使用 2 的最大次方來代表僅可打印的ASCII字符。在 Base64 中的變量使用字符 A—Z、a—z 和 0 —9 共 62 個字符 , 用來作為 Base64 編碼表中的 64 碼 , 最后兩個用作為數(shù)字的符號在不同的系統(tǒng)中而不同。Base64 編碼轉(zhuǎn)換的時候,將三個字節(jié)的數(shù)據(jù) , 先后放入 24 位的緩沖區(qū)中 , 先來的字節(jié)占高位。如果數(shù)據(jù)不足 3 個字節(jié) , 將緩沖區(qū)中剩下的位用 0 補足。然后 , 每次取出 6 位,按照其值選擇ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 中的字符作為編碼后的輸出。不斷進行 , 直到全部輸入數(shù)據(jù)轉(zhuǎn)換完成。
Base64 要求把每三個 8Bit 的字節(jié)按照每 6Bit 一組的長度分割成四組(3 X 8 = 4 X 6 = 24),然后給每組 6Bit 的數(shù)據(jù)添加兩位高位 0,組成四個新的 8Bit 的字節(jié)。也就是說, 轉(zhuǎn)換后的字符串理論上將要比原來的長 1/3。然后將新產(chǎn)生的四個8Bit字節(jié)根據(jù)轉(zhuǎn)換表映射為 ASCII 字符。(最后兩個字符的定義在不同的系統(tǒng)中有所不同)。為了保證所輸出的編碼位可讀字符,Base64制定了一個編碼表,以便進行統(tǒng)一轉(zhuǎn)換。編碼表的大小為2^6=64,這也是Base64名稱的由來。

Base64編碼表

如果原文的字節(jié)數(shù)不是 3 的倍數(shù),即轉(zhuǎn)換到最后 部分時 bit 數(shù)不夠 6 的倍數(shù)時我們規(guī)定,不足的 bit 位 使用全 0 來補足,轉(zhuǎn)換后需要在密文的末尾添加 = 號來標注。如果原文剩余 1 字節(jié)(即需要補足 4 位 0), 那么就在密文末尾添加兩個 = 號,如果原文剩余 2 字節(jié)(即需要補足 2 位 0),則添加一個 = 號。

2. 上代碼。。。。

在iOS7之前我們一般用的都是第三方框架,比如nicklockwood寫的Base64框架還有Google的GTMBase64,雖然蘋果有了自己的實現(xiàn),但是許多其它的加密框架都用到了它,所以還是要了解一下,另外它還提供任意長度字符插入\r\n
,而蘋果只能是64或76長度。

Base64存儲方式(重要):

  • 可見字符串形式
    為了保證所輸出的每一個編碼字節(jié)都是可讀字符,而不是0~63這些數(shù)字,Base64制作了一個碼表,就像ASCII碼表一樣,每一個Base64碼值都有對應的字符。64個可讀字符從0到63非別是A-Z、a-z、0-9、+、/,這也是Base64名字的由來。

  • 以16進制形式
    即NSData形式保存,Base64編碼結(jié)果為字符,而這些字符又對應ASCII碼表的碼值,NSData就是存儲ASCII碼表的碼值。

示例: 蘋果原生API->NSData的擴展:NSData (NSDataBase64Encoding)

假設我們對字符串"123"進行Base64編碼,"123"對應的16進制是313233,二進制為00110001 00110010 00110011,將其變?yōu)?*** 6結(jié)果即下表中的第一行。然后根據(jù)Base64的碼表,它們分別對應表中的第二行。那么"123"編碼的最終結(jié)果即為MTIz,以字符串的形式保存。然后根據(jù)MTIz對應ASCII碼值,以NSData形式存儲,如表中的第三行。

轉(zhuǎn)換為4*6結(jié)果 00001100 00010011 00001000 00110011
Base64對應字符 M T I z
對應ASCII碼值(16進制) 4d 54 49 7a

上面的過程通過代碼實現(xiàn)如下:

//1 待編碼的原始字符串
NSString *plainStr = @"123";
// 2 將其轉(zhuǎn)換成NSData保存,那么"123"對應的ASCII碼表碼值是31、32、33(16進制)
NSData *plainData = [plainStr dataUsingEncoding:NSUTF8StringEncoding];
// 3.1 將其進行Base64編碼,且結(jié)果以字符串形式保存,對應表中的第二行
NSString *baseStr = [plainData base64EncodedStringWithOptions:0];
// 3.2 將其進行Base64編碼,且結(jié)果以NSData形式保存
NSData *base64Data = [plainData base64EncodedDataWithOptions:0];

另外對于參數(shù)NSDataBase64EncodingOptions選項,有多種取值

  • NSDataBase64Encoding64CharacterLineLength:每64個字符插入\r或\n
  • NSDataBase64Encoding76CharacterLineLength:每76個字符插入\r或\n,標準中有要求是76個字符要換行,不過具體還是自己定
  • NSDataBase64EncodingEndLineWithCarriageReturn:插入字符為\r
  • NSDataBase64EncodingEndLineWithLineFeed:插入字符為\n

前兩個選項為是否允許插入字符,以及多少個字符長度插入,兩個可以選其一或者都不選。后兩個選項代表要插入的具體字符。比如我們想76個字符后插入一個\r則可以NSDataBase64Encoding76CharacterLineLength | NSDataBase64EncodingEndLineWithCarriageReturn
。而在上面舉的例子中選項為0,則代表不插入字符。

二、MD5、SHA1、SHA256、SHA512、HMAC

實質(zhì)是抽取特征碼,這樣一般不會重復!不同的文本它的哈希結(jié)果是有可能相同的,但概率很小。(舉例:比如想要識別一個人,我們可以通過他的指紋來鎖定他,指紋出現(xiàn)相同的概率很低吧!在這里,人就相當于數(shù)據(jù),而指紋就相當于對人這個數(shù)據(jù)進行hash后得到的結(jié)果)
對任意一個二進制數(shù)據(jù)進行哈希,可以得到定長的字符串結(jié)果,例如MD5哈希結(jié)果是128bit,更多是以32個字符的十六進制格式哈希輸出
還有就是不可逆的,既然是不可逆的,那么當然不是用來加密的,而是簽名
以MD5為例說明:(SHA實現(xiàn)換湯不換藥,更換實現(xiàn)中的數(shù)據(jù)格式以及加密算法就ok了)

+ (NSString *)md5EncryptStringWithString:(NSString *)str{
    const char *plain = str.UTF8String;
    unsigned char *digest;
    digest = malloc(CC_SHA1_DIGEST_LENGTH);
    
    CC_MD5(plain, (CC_LONG)strlen(plain), digest);
    
    NSString *encode = [self stringFromBytes:digest length:CC_MD5_DIGEST_LENGTH];
    free(digest);
    return encode;
}

+ (NSString *)md5EncryptStringWithData:(NSData *)data{
    
    unsigned char *digest;
    digest = malloc(CC_SHA1_DIGEST_LENGTH);
    
    CC_MD5(data.bytes, (CC_LONG)data.length, digest);
    
    NSString *encode = [self stringFromBytes:digest length:CC_MD5_DIGEST_LENGTH];
    free(digest);
    return encode;
}

+ (NSData *)md5EncryptDataWithString:(NSString *)str{
    const char *plain = str.UTF8String;
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    
    CC_MD5(plain, (CC_LONG)strlen(plain), result);
    
    return [[NSData alloc] initWithBytes:result length:CC_MD5_DIGEST_LENGTH];
}

+ (NSData *)md5EncryptDataWithData:(NSData *)data{
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    
    CC_MD5(data.bytes, (CC_LONG)data.length, result);
    
    return [NSData dataWithBytes:result length:CC_MD5_DIGEST_LENGTH];
}

補充說明:

  1. MD5一些算法
  1. 以NSData輸出,是以dataWithBytes:length:方法獲取(byte和長度)
  1. 以NSString輸出,蘋果沒有相關的方法提供,見下面實現(xiàn)
+ (NSString *)stringFromBytes:(uint8_t *)bytes length:(int)length {
    NSMutableString *strM = [NSMutableString string];
    
    for (int i = 0; i < length; i++) {
        //此處%02X中X的大小寫決定了輸出字母的大小寫
        [strM appendFormat:@"%02X", bytes[i]];
    }
    
    return [strM copy];
}

以HMACMD5為例說明HAMAC:
HMAC是密鑰相關的哈希運算消息認證碼(Hash-based Message Authentication Code),HMAC運算利用哈希算法,以一個密鑰和一個消息為輸入,生成一個消息摘要作為輸出。個人感覺有秘鑰會更安全一點,但是HTTPS才是以后發(fā)展王道。。。。。下面實現(xiàn)有字符串輸出的依然參考上面stringFromBytes:length:

+ (NSString *)hmacMD5EncryptStringWithString:(NSString *)str andKey:(NSString *)key{
    const char *keyData = key.UTF8String;
    const char *strData = str.UTF8String;
    uint8_t buffer[CC_MD5_DIGEST_LENGTH];
    
    CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), strData, strlen(strData), buffer);
    
    
    return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}

+ (NSString *)hmacMD5EncryptStringWithData:(NSData *)data andKey:(NSString *)key{
    const char *keyData = key.UTF8String;
    //    const char *strData = str.UTF8String
    uint8_t buffer[CC_MD5_DIGEST_LENGTH];
    
    CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), [data bytes], [data length], buffer);
    
    
    return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}

+ (NSData *)hmacMD5EncryptDataWithString:(NSString *)str andKey:(NSString *)key{
    const char *keyData = key.UTF8String;
    const char *strData = str.UTF8String;
    unsigned char hash[CC_MD5_DIGEST_LENGTH];

    CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), strData, strlen(strData), hash);

    return ( [NSData dataWithBytes: hash length: CC_MD5_DIGEST_LENGTH] );
}
+ (NSData *)hmacMD5EncryptDataWithData:(NSData *)data andKey:(NSString *)key{
    const char *keyData = key.UTF8String;
    unsigned char hash[CC_MD5_DIGEST_LENGTH];
    
    CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), data.bytes, data.length, hash);
    
    return ( [NSData dataWithBytes: hash length: CC_MD5_DIGEST_LENGTH] );
}

三、AES

AES加密過程涉及到4種操作:字節(jié)替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)輪密鑰加(AddRoundKey)。解密過程分別為對應的逆操作。由于每一步操作都是可逆的,按照相反的順序進行解密即可恢復明文。加解密中每輪的密鑰分別由初始密鑰擴展得到。算法中16字節(jié)的明文、密文和輪密鑰都以一個4x4的矩陣表示。
說明:AES根據(jù)秘鑰的長度不同分為AES128、AES129、AES256;AES細分又有很多加密模式(ECB、CBC、CFB、OFB),一般開發(fā)常用的有ECB和CBC。

  • ECB(Electronic Code Book,電子密碼本)模式
    是一種基礎的加密方式,要加密的數(shù)據(jù)被分割成分組長度相等的塊,不足補齊,然后單獨的一個個組加密,合在一起輸出組成密文。
    優(yōu)點: 1.簡單; 2.有利于并行計算; 3.誤差不會被擴散;
    缺點: 1.不能隱藏明文的模式; 2.可能對明文進行主動攻擊;
    因此,此模式適于加密小消息。
  • CBC(Cipher Block Chaining,加密塊鏈)模式
    是一種循環(huán)模式,也將要加密的數(shù)據(jù)分割為長度相等的組,不足補齊,前一個分組的密文和當前分組的明文異或操作后再加密,這樣做的目的是增強破解難度,會比ECB安全一點。
    優(yōu)點: 不容易主動攻擊,安全性好于ECB,適合傳輸長度長的報文,是SSL、IPSec的標準。
    缺點: 1.不利于并行計算; 2.誤差傳遞; 3.需要初始化向量IV

AES加密

/// 默認使用kCCOptionPKCS7Padding填充
#define kPaddingMode kCCOptionPKCS7Padding
/*
 默認CBC模式,返回base64編碼
 */
- (NSString *)aesEncryptWithHexKey:(NSString *)key hexIv:(NSString *)iv {
    NSData *aesKey = [key dataFromHexString];
    if (iv == nil) {
        // 32長度
        iv = @"00000000000000000000000000000000";
    }
    NSData *aesIv = [iv dataFromHexString];
    NSData *resultData = [self aesEncryptWithDataKey:aesKey dataIv:aesIv];
    return [resultData base64EncodedStringWithOptions:0];
}

/*
 默認CBC模式,返回base64編碼
 */
- (NSString *)aesEncryptWithKey:(NSString *)key iv:(NSString *)iv {
    NSData *aesKey = [key dataUsingEncoding:NSUTF8StringEncoding];
    if (iv == nil) {
        // 32長度
        iv = @"00000000000000000000000000000000";
    }
    NSData *aesIv = [iv dataUsingEncoding:NSUTF8StringEncoding];
    NSData *resultData = [self aesEncryptWithDataKey:aesKey dataIv:aesIv];
    return [resultData base64EncodedStringWithOptions:0];
}

/*
 CBC模式,返回NSData
 */
- (NSData *)aesEncryptWithDataKey:(NSData *)key dataIv:(NSData *)iv {
    return [self aesEncryptOrDecrypt:kCCEncrypt data:[self dataUsingEncoding:NSUTF8StringEncoding] dataKey:key dataIv:iv mode:kPaddingMode];
}

/*
 ECB模式,返回base64編碼
 */
- (NSString *)aesECBEncryptWithHexKey:(NSString *)key {
    NSData *aesKey = [key dataFromHexString];
    NSData *resultData = [self aesECBEncryptWithDataKey:aesKey];
    return [resultData base64EncodedStringWithOptions:0];
}

/*
 ECB模式,返回base64編碼
 */
- (NSString *)aesECBEncryptWithKey:(NSString *)key {
    NSData *aesKey = [key dataUsingEncoding:NSUTF8StringEncoding];
    NSData *resultData = [self aesECBEncryptWithDataKey:aesKey];
    return [resultData base64EncodedStringWithOptions:0];
}

/*
 ECB模式,返回NSData
 */
- (NSData *)aesECBEncryptWithDataKey:(NSData *)key {
    NSData *aesIv = [@"00000000000000000000000000000000" dataFromHexString];
    return [self aesEncryptOrDecrypt:kCCEncrypt data:[self dataUsingEncoding:NSUTF8StringEncoding] dataKey:key dataIv:aesIv mode:kPaddingMode | kCCOptionECBMode];
}

AES解密

/*
 默認CBC模式解密,默認string為base64格式
 */
- (NSString *)aesBase64StringDecryptWithHexKey:(NSString *)key hexIv:(NSString *)iv {
    NSData *aesKey = [key dataFromHexString];
    if (iv == nil) {
        // 32長度
        iv = @"00000000000000000000000000000000";
    }
    NSData *aesIv = [iv dataFromHexString];
    NSData *data = [[NSData alloc] initWithBase64EncodedString:self options:0];
    NSData *resultData = [NSString aesDecryptWithData:data dataKey:aesKey dataIv:aesIv];
    return [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
}

/*
 CBC模式解密,返回NSData
 */
+ (NSData *)aesDecryptWithData:(NSData *)data dataKey:(NSData *)key dataIv:(NSData *)iv {
    return [[NSString alloc] aesEncryptOrDecrypt:kCCDecrypt data:data dataKey:key dataIv:iv mode:kPaddingMode];
}

/*
 ECB模式解密,返回base64編碼
 */
- (NSString *)aesECBDecryptWithHexKey:(NSString *)key {
    NSData *aesKey = [key dataFromHexString];
    NSData *resultData = [self aesECBEncryptWithDataKey:aesKey];
    return [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];;
}

/*
 ECB模式解密,返回NSData
 */
- (NSData *)aesECBDecryptWithDataKey:(NSData *)key {
    NSData *aesIv = [@"00000000000000000000000000000000" dataFromHexString];
    return [self aesEncryptOrDecrypt:kCCDecrypt data:[self dataUsingEncoding:NSUTF8StringEncoding] dataKey:key dataIv:aesIv mode:kPaddingMode | kCCOptionECBMode];
}

補充說明:
這個運算會根據(jù)傳入key的長度進行識別,只是加密的輪數(shù)不同

- (NSData *)aesEncryptOrDecrypt:(CCOperation)option data:(NSData *)data dataKey:(NSData *)key dataIv:(NSData *)iv mode:(int)mode{
    // check length of key and iv
    if ([iv length] != 16) {
        @throw [NSException exceptionWithName:@"Encrypt"
                                       reason:@"Length of iv is wrong. Length of iv should be 16(128bits)"
                                     userInfo:nil];
    }
    if ([key length] != 16 && [key length] != 24 && [key length] != 32 ) {
        @throw [NSException exceptionWithName:@"Encrypt"
                                       reason:@"Length of key is wrong. Length of iv should be 16, 24 or 32(128, 192 or 256bits)"
                                     userInfo:nil];
    }
    
    // setup output buffer
    size_t bufferSize = [data length] + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    // do encrypt
    size_t encryptedSize = 0;
    CCCryptorStatus cryptStatus = CCCrypt(option,
                                          kCCAlgorithmAES128,
                                          mode,
                                          [key bytes],     // Key
                                          [key length],    // kCCKeySizeAES
                                          [iv bytes],      // IV
                                          [data bytes],
                                          [data length],
                                          buffer,
                                          bufferSize,
                                          &encryptedSize);
    NSData *resultData = nil;
    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytes:buffer length:encryptedSize];        
        free(buffer);
        return resultData;
    } else {
        free(buffer);
        @throw [NSException exceptionWithName:@"Encrypt"
                                       reason:@"Encrypt Error!"
                                     userInfo:nil];
        return resultData;
    }
    return resultData;
}

四、RSA

使用說明

假設A、B雙方均擁有一對公私鑰(PUB_APRI_A、PUB_B、PRI_B)。

A向B發(fā)送Message的整個簽名和加密的過程如下:

  1. A先使用HASH對Message生成一個固定長度的信息摘要Message_hash_A
  2. A使用A的私鑰PRI_AMessage_hash_A進行簽名得到Message_sign(這里為什么不直接對Message進行簽名,而要對Message_hash_A進行簽名呢?因為Message的長度可能很長,而Message_hash_A的長度則是固定的,這樣性能更高,格式也固定,況且hash的結(jié)果一般不會出現(xiàn)重復的可能)
  3. A接著使用B的公鑰PUB_B對信息Message和信息Message_sign進行加密得到Message_RSA,這時A將Message_RSA發(fā)送給B。

當B接收到A的信息Message_RSA后,獲取Message的步驟如下:

  1. B用自己的私鑰PRI_B解密得到明文:MessageMessage_sign;
  2. 然后B使用A的公鑰PUB_AMessage_sign得到Message_hash_A;同時,B再對Message使用與A相同的HASH得到Message_hash_B;
  3. 如果Message_hash_AMessage_hash_B相同,則說明Message沒有被篡改過。

秘鑰生成方法
先cd 一個文件夾 生成的pem文件就在這個文件夾下面,以文本編輯器方式打開。。。。。

  • 生成私鑰,1024bit,PKCS1Padding格式,Base64編碼
命令行:openssl genrsa -out rsa_private_key.pem 1024

結(jié)果如下:
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDOxoZIsFbFMeR0OWnc/sF5A3Gj0BWsoClQW3BKgvMQ85ZXVCM6
7g6XItl5sSW2EyMaIeQ8tRsM0HI4oCvlOMjSVgdyZmqbUfaZDoDYPW2pDbLqMDr/
o1eKxYpssbAyH6ZDyJeTOEu9yF7XUsIilokzc0D9i+uPc8yp/vLYTPDJEQIDAQAB
AoGAFUMevcy8L2zQ9A6PTzU3Cc2L2u9juyuA9A1i/5Z1jhGuLO6u7Llb8LiZqkTH
/u/61Q4VHRT2YhvxEteNi/WJ2L+1wTZYWbE/NIHBls4dTDt4aiMGUG2y6uBcFPmB
97sjT3ofcOHVZuFc80ktyhVuvx5osB8obZHbjn+3hn/pIF0CQQDx1bollu3XXL08
YJrS1mpB3F/87HXcxDa0dWUoqBRUCPjqC+8SuxaddPK6RFvkb1UyWJNzQ5Mb3OZt
65/sipdDAkEA2uMWf0ukTRhxiEYhZIJDSaERYeaWFU+mc6mC2//Tcvy7hldBe15n
7UQNKWl7DbI3Z7NmuKPa+rWqwASqtBAHGwJAOav7iW1V6Q8fvd9X7MHfczdn2LxX
Wz+bwCti5XA38NZ27fHMoM3nFcPHAu68b1yxl6ESAOHzmihy93HCoLloWwJARodX
j2rTJRhUNMHMLrOedNIWZMJE59cDXk9nX/X9rxZqYi4pZlQUDqqXxxk60j3zhlGT
Lrl1bMUuoLKgQmbLswJAIfv1Vw18YcEexWPBkn5iKufu0Fo7+Z776lDLYP1kNyQZ
eohofAAWYNQvHZ4WTpiIxi2FZ9xIRu+M7smsIs0h2g==
-----END RSA PRIVATE KEY-----
  • 根據(jù)上面的私鑰生成公鑰
命令行:openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout

結(jié)果如下:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOxoZIsFbFMeR0OWnc/sF5A3Gj
0BWsoClQW3BKgvMQ85ZXVCM67g6XItl5sSW2EyMaIeQ8tRsM0HI4oCvlOMjSVgdy
ZmqbUfaZDoDYPW2pDbLqMDr/o1eKxYpssbAyH6ZDyJeTOEu9yF7XUsIilokzc0D9
i+uPc8yp/vLYTPDJEQIDAQAB
-----END PUBLIC KEY-----
  • 將私鑰生成pkcs8格式,可在iOS工程中直接使用
openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt

結(jié)果:
-----BEGIN PRIVATE KEY-----
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAM7GhkiwVsUx5HQ5
adz+wXkDcaPQFaygKVBbcEqC8xDzlldUIzruDpci2XmxJbYTIxoh5Dy1GwzQcjig
K+U4yNJWB3JmaptR9pkOgNg9bakNsuowOv+jV4rFimyxsDIfpkPIl5M4S73IXtdS
wiKWiTNzQP2L649zzKn+8thM8MkRAgMBAAECgYAVQx69zLwvbND0Do9PNTcJzYva
72O7K4D0DWL/lnWOEa4s7q7suVvwuJmqRMf+7/rVDhUdFPZiG/ES142L9YnYv7XB
NlhZsT80gcGWzh1MO3hqIwZQbbLq4FwU+YH3uyNPeh9w4dVm4VzzSS3KFW6/Hmiw
HyhtkduOf7eGf+kgXQJBAPHVuiWW7ddcvTxgmtLWakHcX/zsddzENrR1ZSioFFQI
+OoL7xK7Fp108rpEW+RvVTJYk3NDkxvc5m3rn+yKl0MCQQDa4xZ/S6RNGHGIRiFk
gkNJoRFh5pYVT6ZzqYLb/9Ny/LuGV0F7XmftRA0paXsNsjdns2a4o9r6tarABKq0
EAcbAkA5q/uJbVXpDx+931fswd9zN2fYvFdbP5vAK2LlcDfw1nbt8cygzecVw8cC
7rxvXLGXoRIA4fOaKHL3ccKguWhbAkBGh1ePatMlGFQ0wcwus5500hZkwkTn1wNe
T2df9f2vFmpiLilmVBQOqpfHGTrSPfOGUZMuuXVsxS6gsqBCZsuzAkAh+/VXDXxh
wR7FY8GSfmIq5+7QWjv5nvvqUMtg/WQ3JBl6iGh8ABZg1C8dnhZOmIjGLYVn3EhG
74zuyawizSHa
-----END PRIVATE KEY-----
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 之前的項目中接觸過一些加密的方法,也沒有太仔細的進行記錄和研究。最近在寫SDK時,加密模塊的占比相當之大;借此時機...
    大雄記閱讀 11,141評論 20 63
  • 概述 之前一直對加密相關的算法知之甚少,只知道類似DES、RSA等加密算法能對數(shù)據(jù)傳輸進行加密,且各種加密算法各有...
    Henryzhu閱讀 3,234評論 0 14
  • 這篇文章主要講述在Mobile BI(移動商務智能)開發(fā)過程中,在網(wǎng)絡通信、數(shù)據(jù)存儲、登錄驗證這幾個方面涉及的加密...
    雨_樹閱讀 3,057評論 0 6
  • 我們花了三年的時間學會說話,卻要用一輩子的時間學會閉嘴??梢?,說話是一門藝術活,學會閉嘴更是尤為重要。 ...
    Ms_珍小姐閱讀 580評論 0 0
  • 我的母親是一位地地道道的農(nóng)民,她善良,美麗,執(zhí)著,熱情。曾經(jīng)的我沒發(fā)現(xiàn)母親的美麗,隨著歲月的沉淀和閱歷的增加慢慢的...
    liu佳閱讀 245評論 0 0

友情鏈接更多精彩內(nèi)容