对密码学的一点研究

加密的方法:(1)对称加密(2)非对称加密

解析:

(1)对称加密:也就是加密的key和解密的key是一样的,这样就叫做对称加密常见的加密算法有AES,DES等

(2)非对称加密:一般需要公钥和私钥,如果两方需要通信,那么,两方分别用对方的公钥加密,用自己的私钥解密

我们平常用的最多的时AES,DES对称加密算法:

对于对称加密又分为:

(1)分组密码,也叫块加密(block cyphers),一次加密明文中的一个块。是将明文按一定的位长分组,明文组经过加密运算得到密文组,密文组经过解密运算(加密运算的逆运算),还原成明文组。
(2)序列密码,也叫流加密(stream cyphers),一次加密明文中的一个位。是指利用少量的密钥(制乱元素)通过某种复杂的运算(密码算法)产生大量的伪随机位流,用于对明文位流的加密。
解密是指用同样的密钥和密码算法及与加密相同的伪随机位流,用以还原明文位流。

在分组加密算法中,有ECB,CBC,CFB,OFB这几种算法模式。

1)ECB(Electronic Code Book)/电码本模式



1.简单,有利于并行计算,误差不会被传送;
2.不能隐藏明文的模式;
repetitions in message may show in cipher text/在密文中出现明文消息的重复 
3.可能对明文进行主动攻击;
加密消息块相互独立成为被攻击的弱点/weakness due to encrypted message blocks being independent

2)CBC(Cipher Block Chaining)



这个词在分组密码中经常会用到,它是指一个明文分组在被加密之前要与前一个的密文分组进行异或运算。当加密算法用于此模式的时候除密钥外,还需协商一个初始化向量(IV),这个IV没有实际意义,只是在第一次计算的时候需要用到而已。采用这种模式的话安全性会有所提高。
1. 不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。
each ciphertext block depends on all message blocks/每个密文块依赖于所有的信息块
thus a change in the message affects all ciphertext blocks/明文消息中一个改变会影响所有密文块
2. need Initial Vector (IV) known to sender & receiver/发送方和接收方都需要知道初始化向量 
3.加密过程是串行的,无法被并行化(在解密时,从两个邻接的密文块中即可得到一个平文块。因此,解密过程可以被并行化);误差传递

3)Cipher Feedback (CFB)


密文反馈(CFB,Cipher feedback)模式类似于CBC,可以将块密码变为自同步的流密码;工作过程亦非常相似,CFB的解密过程几乎就是颠倒的CBC的加密过程:
需要使用一个与块的大小相同的移位寄存器,并用IV将寄存器初始化。然后,将寄存器内容使用块密码加密,然后将结果的最高x位与平文的x进行异或,以产生密文的x位。下一步将生成的x位密文移入寄存器中,并对下面的x位平文重复这一过程。解密过程与加密过程相似,以IV开始,对寄存器加密,将结果的高x与密文异或,产生x位平文,再将密文的下面x位移入寄存器。
与CBC相似,平文的改变会影响接下来所有的密文,因此加密过程不能并行化;而同样的,与CBC类似,解密过程是可以并行化的。

4)Output Feedback (OFB)


输出反馈模式(Output feedback, OFB)可以将块密码变成同步的流密码。它产生密钥流的块,然后将其与平文块进行异或,得到密文。与其它流密码一样,密文中一个位的翻转会使平文中同样位置的位也产生翻转。这种特性使得许多错误校正码,例如奇偶校验位,即使在加密前计算而在加密后进行校验也可以得出正确结果。
每个使用OFB的输出块与其前面所有的输出块相关,因此不能并行化处理。然而,由于平文和密文只在最终的异或过程中使用,因此可以事先对IV进行加密,最后并行的将平文或密文进行并行的异或处理。
可以利用输入全0的CBC模式产生OFB模式的密钥流。这种方法十分实用,因为可以利用快速的CBC硬件实现来加速OFB模式的加密过程。

下面我们在讲解一下,在我们的实际应用中用到的函数:

加密函数需要四个参数:Key(密码)、Data(要加密的数据)、Mode(模式[上面说得几种模式])以及FILL(填充)还有一种大家可能都很少用的iv(协商一个初始化向量(IV),这个IV没有实际意义,只是在第一次计算的时候需要用到而已。)

首先说下填充

mac支持:
NoPadding //kCCOptionECBMode

PKCS7Padding//kCCOptionPKS7Padding
而java支持:
NoPadding
ISO10126Padding
OAEPPadding, OAEPWithAndPadding
PKCS1Padding
PKCS5Padding
SSL3Padding

NoPadding就是不填充,相当于自定义填充,显然太麻烦。
除此之外,就没有相同的了。
在iOS中创建CCCryptorStatus:

    ccStatus = CCCrypt(encryptOrDecrypt,

                       kCCAlgorithm3DES,

                       kCCOptionECBMode|kCCOptionPKCS7Padding,

                       vkey, //"123456789012345678901234", //key

                       kCCKeySize3DES,

                       vinitVec, //"init Vec", //iv,

                       vplainText, //"Your Name", //plainText,

                       plainTextBufferSize,

                       (void *)bufferPtr,

                       bufferPtrSize,

                       &movedBytes);

其中kCCOptionECBMode|kCCOptionPKCS7Padding两个都选择就与java中PKCS5Padding模式相同了(我能说点什么呢)

下面是一个AES128的加密算法,同时,在不够16个字符的情况下,用\0进行填充。

//需要包含的头文件:

#import

#import


#define FBENCRYPT_ALGORITHM     kCCAlgorithmAES128

#define FBENCRYPT_BLOCK_SIZE    kCCBlockSizeAES128

#define FBENCRYPT_KEY_SIZE      kCCKeySizeAES128

///开始加密

    NSData * postdata = [@"12345678" dataUsingEncoding:NSUTF8StringEncoding];//数据

    NSData* key = [@"123" dataUsingEncoding:NSUTF8StringEncoding];//加密的key

    NSData* iv = nil;//初始向量

    NSData* encryptedData = [self encryptData:postdata key:key iv:iv];//加密算法

    postdata = encryptedData;    

    NSString * str = [[NSString alloc] initWithData:postdata encoding:NSUTF8StringEncoding];

/函数实现;

-(NSData*)encryptData:(NSData*)data key:(NSData*)key iv:(NSData*)iv;

{

    NSData* result = nil;

    // setup key

    unsigned char cKey[FBENCRYPT_KEY_SIZE];

bzero(cKey, sizeof(cKey));

    [key getBytes:cKey length:FBENCRYPT_KEY_SIZE];

    // setup iv

    char cIv[FBENCRYPT_BLOCK_SIZE];

    bzero(cIv, FBENCRYPT_BLOCK_SIZE);

    if (iv) {

        [iv getBytes:cIv length:FBENCRYPT_BLOCK_SIZE];

    }

     // setup output buffer

    int length = [data length];

    int sendLength = 16 - (length %16);

    if(sendLength != 16)

    {

        sendLength = length + sendLength;

    }else

    {

        sendLength = length;

    }

     size_t bufferSize = sendLength;

void *buffer = malloc(bufferSize+1);

    bzero(buffer, bufferSize + 1); 

    char* pChar =(char * )([data bytes]);

    char * pMiddle = (char * )(malloc(sendLength + 1));

    bzero(pMiddle, sendLength + 1);

    memcpy(pMiddle, pChar, length );

    

    // do encrypt

size_t encryptedSize = 0;

CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,

                                          FBENCRYPT_ALGORITHM,

                                          kCCOptionECBMode ,

                                          cKey,

                                          FBENCRYPT_KEY_SIZE,

                                          cIv,

                                          pMiddle,

                                          sendLength,

                                          buffer,

                                          bufferSize,

  &encryptedSize);

if (cryptStatus == kCCSuccess) {

result = [NSData dataWithBytes:buffer length:encryptedSize];

} else {

        NSLog(@"[ERROR] failed to encrypt|CCCryptoStatus: %d", cryptStatus);

    }

    free(buffer);

    free(pMiddle);

return result;

}

下面是解密算法

key = "123"

iv = nil;

(NSData*)decryptData:(NSData*)data key:(NSData*)key iv:(NSData*)iv;

{

    NSData* result = nil;

    

    // setup key

    unsigned char cKey[FBENCRYPT_KEY_SIZE];

bzero(cKey, sizeof(cKey));

    [key getBytes:cKey length:FBENCRYPT_KEY_SIZE];

    // setup iv

    char cIv[FBENCRYPT_BLOCK_SIZE];

    bzero(cIv, FBENCRYPT_BLOCK_SIZE);

    if (iv) {

        [iv getBytes:cIv length:FBENCRYPT_BLOCK_SIZE];

    }

    

    // setup output buffer

    int length = [data length];

    int sendLength = 16 - (length %16);

    if(sendLength != 16)

    {

        sendLength = length + sendLength;

    }else

    {

        sendLength = length;

    }

    

size_t bufferSize = sendLength;

void *buffer = malloc(bufferSize+1);

    bzero(buffer, bufferSize + 1);

    

    

    char* pChar =(char * )([data bytes]);

    char * pMiddle = (char * )(malloc(sendLength + 1));

    bzero(pMiddle, sendLength + 1);

    memcpy(pMiddle, pChar, length );

    

    // do encrypt

size_t encryptedSize = 0;

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,

                                          FBENCRYPT_ALGORITHM,

                                          kCCOptionECBMode ,

                                          cKey,

                                          FBENCRYPT_KEY_SIZE,

                                          cIv,

                                          pMiddle,

                                          sendLength,

                                          buffer,

                                          bufferSize,

  &encryptedSize);

if (cryptStatus == kCCSuccess) {

result = [NSData dataWithBytes:buffer length:encryptedSize];

} else {

        NSLog(@"[ERROR] failed to encrypt|CCCryptoStatus: %d", cryptStatus);

    }

    free(buffer);

    free(pMiddle);

return result;



}

得到最后的字符串用:

[[NSString alloc] initWithData:target encoding:NSUTF8StringEncoding];来进行转化为NSString;




你可能感兴趣的:(mac,ios)