对称密钥加密
对称加密相对好理解,加密方和解密方使用的是同一个密钥。
常见的对称密钥加密有AES、DES 等。
MD5
MD5是一个哈希算法,对同一个明文生成的密文(哈希值)是统一的。MD5相较于普通加密来说还有一个优点:MD5生成的密文长度很短(16位或者32位字符)。全称MD5消息摘要算法(MD5 Message-Digest Algorithm)。
非对称密钥加密
非对称密钥加密,又称为公开密钥加密。
非对称密钥加密需要两个密钥,一个是公开密钥,一个是私有密钥。私有密钥用来加密,公开密钥用来解密。私有密钥由加密方保管,公有密钥则公布出来。
实际上,私有密钥和共有密钥在数学上是有一定的关系的。但是仅仅从共有密钥是推断不出私有密钥的,这也是共有密钥可以公布出来的原因。
通过共有密钥推断私有密钥和质数分解有关。目前质数分解没有特别快的算法,通常是通过暴力枚举的方法来分解。当质数非常大时(如2的1024次方级别),暴力分解质数是不现实的,因此非对称加密是安全的。
非对称加密的安全还依赖于加密方对私钥的管理,一旦私钥暴露,也就毫无加密可言。
常见的非对称加密有RSA、DSA。
数字签名
数字签名用的是非对称加密,公开密钥在数据接收方,数字签名的作用是保证:
- 保证数据没有没有被篡改过
- 保证数据是经过我认证的
- 首先算出原始数据的摘要。这里的算法要保证:如果原始数据有任何变化,则摘要也会发生变化;对同一份原始数据,使用相同的算法,计算出的摘要是相同的。这一步使用的算法通常是MD5消息摘要算法。
- 生成一对公钥和私钥,使用非对称加密方式,用私钥对上一步生成的摘要进行加密,加密的结果就是数字签名。
- 在返回数据时,将原始数据和数字签名一起返回给请求数据方。
接到数据之后就行验证数据的完整性:
- 首先用含有的公钥对数字签名进行解密,如果能够解密成功,说明返回的数据是经过数据发送方认证的(否则数据发送方不会对该数据加密)。
- 对原始的数据使用MD5算法,生成原始数据的摘要。
- 对比第一步和第二步生成的摘要,如果生成的摘要相等,说明原始数据没有被篡改过。
由此,通过数字签名可以达到确保数据没有被篡改过以及数据是合法的目的。
DES加解密
这里使用框架提供的des加解密库:
首先引入头文件 #import CommonCrypto/CommonCryptor.h
主要的加解密函数如下:
/*字符串加密
*参数
*plainText : 加密明文
*key : 密钥 64位
*/
+ (NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key
{
NSString *ciphertext = nil;
const char *textBytes = [plainText UTF8String];
NSUInteger dataLength = [plainText length];
unsigned char buffer[1024];
memset(buffer, 0, sizeof(char));
Byte iv[] = {1,2,3,4,5,6,7,8};
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding,
[key UTF8String], kCCKeySizeDES,
iv,
textBytes, dataLength,
buffer, 1024,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
ciphertext = [[[NSString alloc] initWithData:[GTMBase64 encodeData:data] encoding:NSUTF8StringEncoding] autorelease];
}
return ciphertext;
}
//解密
+ (NSString *) decryptUseDES:(NSString*)cipherText key:(NSString*)key
{
NSData* cipherData = [GTMBase64 decodeString:cipherText];
unsigned char buffer[1024];
memset(buffer, 0, sizeof(char));
size_t numBytesDecrypted = 0;
Byte iv[] = {1,2,3,4,5,6,7,8};
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding,
[key UTF8String],
kCCKeySizeDES,
iv,
[cipherData bytes],
[cipherData length],
buffer,
1024,
&numBytesDecrypted);
NSString* plainText = nil;
if (cryptStatus == kCCSuccess) {
NSData* data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];
plainText = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
}
return plainText;
}
MD5加密
MD5加密是不可逆的
MD5实现方法(16位):
+ (NSString *)md5:(NSString *)str
{
constchar *concat_str = [strUTF8String];
unsignedchar result[CC_MD5_DIGEST_LENGTH];
CC_MD5(concat_str, (unsignedint)strlen(concat_str), result);
NSMutableString *hash = [NSMutableStringstring];
for (int i =0; i <16; i++){
[hashappendFormat:@"%02X", result[i]];
}
return [hashuppercaseString];
}
AES加密
对称加密,密钥key
常用的,详解:
h文件内容:
#import
@class NSString;
@interface NSData (Encryption)
- (NSData *)AESOverCycle:(NSString *)key; //加密
- (NSData *)AESRelaes:(NSString *)key; //解密
@end
m文件内容:
加密:
@implementation NSData (Encryption)
- (NSData *)AESOverCycle:(NSString *)key {
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
解密:
- (NSData *)AESRelaes:(NSString *)key {
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
@end
Base64编码与解码
Base64编码是6个二进制位一编码, ASCII码是8个二进制位一编码,所以转换成字符串后会比ASCII内容要多。其使用64个字符来对任意数据进行编码。
Base64编码本质上是一种将二进制数据转成文本数据的方案。对于非二进制数据,是先将其转换成二进制形式,然后每连续6比特(2的6次方=64)计算其十进制值,根据该值在上面的索引表中找到对应的字符,最终得到一个文本字符串。
Base64是一个可逆过程,不能用作数据加密操作。