加密一般分为 对称加密和非对称加密。
—、对称加密
对称密码学分成分组密码和序列密码(流密码)两部分,他们差异较大易于区分。
序列密码 序列密码单独加密每个位。它是通过将密钥序列中的每个位于每个明文位相加实现的。同步序列密码的密码序列仅仅取决于密钥,而异步序列密码的密钥序列则取决于密钥和密文。密码反馈(cipher Feedback,CFB)模式是异步序列密码
分组密码 分组密码每次使用相同的密钥加密整个明文位分组。这意味着给定分组内任何明文的加密都要依赖于与它同在一个分组内的其他所有的明文位。实际中,绝大多数分组密码的分组长度要么是128位(16字节),比如高级加密标准(AES),要么是64位(8字节),比如数据加密标准(DES)或三重DES(3DES)算法。
二、非对称加密
非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey) 公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密 如RSA ECC DSA。
非对称密码体制的特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快 对称密码体制中只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥。所以保证其安全性就是保证密钥的安全,而非对称密钥体制有两种密钥,其中一个是公开的,这样就可以不需要像对称密码那样传输对方的密钥了
###DES加密算法
DES加密算法是一种分组密码,以64位为分组对数据加密,它的密钥长度是56位,加密解密用同一算法。DES加密算法是对密钥进行保密,而公开算法,包括加密和解密算法。这样,只有掌握了和发送方相同密钥的人才能解读由DES加密算法加密的密文数据。因此,破译DES加密算法实际上就是搜索密钥的编码。对于56位长度的密钥来说,如果用穷举法来进行搜索的话,其运算次数为256。 一般是通过穷举算法破解
随着计算机系统能力的不断发展,DES的安全性比它刚出现时会弱得多,然而从非关键性质的实际出发,仍可以认为它是足够的。不过,DES现在仅用于旧系统的鉴定,而更多地选择新的加密标准。
###RSA加密算法 RSA加密算法是目前最有影响力的公钥加密算法,并且被普遍认为是目前最优秀的公钥方案之一。RSA是第一个能同时用于加密和数宇签名的算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA加密算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。 基本加密原理: (1)找出两个“很大”的质数:P & Q (2)N = P * Q (3)M = (P – 1) * (Q – 1) (4)找出整数E,E与M互质,即除了1之外,没有其他公约数 (5)找出整数D,使得E*D除以M余1,即 (E * D) % M = 1 经过上述准备工作之后,可以得到: E是公钥,负责加密 D是私钥,负责解密 N负责公钥和私钥之间的联系 加密算法,假定对X进行加密 (X ^ E) % N = Y n根据费尔马小定义,根据以下公式可以完成解密操作 (Y ^ D) % N = X
但是RSA加密算法效率较差,对大型数据加密时间很长,一般用于小数据。 我们app已经放弃了采用RSA加密算法。
Hash算法
HASH算法是一种单向算法,通过特定HASH算法可以对原始数据生成特定的HASH值数据,但是反向不可逆的,严格意义上来说这不是一种加密算法; 例如MD5 ,主要用于密码存储。例如各大型门户网站存储的用户密码的数据形式应该是HASH算法之后的形式。
###MD5 (不是加密算法)
MD5为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。对MD5加密算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成—个128位散列值。
MD5被广泛用于各种软件的密码认证和钥匙识别上。MD5用的是哈希函数,它的典型应用是对一段信息产生信息摘要,以防止被篡改。MD5的典型应用是对一段Message产生fingerprin指纹,以防止被“篡改”。如果再有—个第三方的认证机构,用MD5还可以防止文件作者的“抵赖”,这就是所谓的数字签名应用。MD5还广泛用于操作系统的登陆认证上,如UNIX、各类BSD系统登录密码、数字签名等诸多方。
MD5是不可逆算法,目前看来只能通过暴力破解的方式。我们用的比较多的是登陆密码的保存 信息完整性验证。 输入的密码MD5值和原先登陆过的MD5值相同说明登入成功。
###SHA1加密算法(安全哈希算法)(不是加密算法)
SHA1是和MD5一样流行的消息摘要算法。SHA加密算法模仿MD4加密算法。SHA1设计为和数字签名算法(DSA)一起使用。
SHA1主要适用于数字签名标准里面定义的数字签名算法。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。SHA1不可以从消息摘要中复原信息,而两个不同的消息不会产生同样的消息摘要。这样,SHA1就可以验证数据的完整性,所以说SHA1是为了保证文件完整性的技术。
SHA1加密算法可以采用不超过264位的数据输入,并产生一个160位的摘要。输入被划分为512位的块,并单独处理。160位缓冲器用来保存散列函数的中间和最后结果。缓冲器可以由5个32位寄存器(A、B、C、D和E)来表示。SHA1是一种比MD5的安全性强的算法,理论上,凡是采取“消息摘要”方式的数字验证算法都是有“碰撞”的——也就是两个不同的东西算出的消息摘要相同,互通作弊图就是如此。但是安全性高的算法要找到指定数据的“碰撞”很困难,而利用公式来计算“碰撞”就更困难一目前为止通用安全算法中仅有MD5被破解。
###Base64加密算法(不是加密算法)
Base64加密算法是网络上最常见的用于传输8bit字节代码的编码方式之一,Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在JAVA PERSISTENCE系统HIBEMATE中,采用了Base64来将一个较长的唯一标识符编码为一个字符串,用作HTTP表单和HTTPGETURL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
我们app用的比较多也是采用Base64编码URL中的数据
###AES加密算法
AES加密算法是密码学中的高级加密标准,该加密算法采用对称分组密码体制,密钥长度的最少支持为128、192、256,分组长度128位,算法应易于各种硬件和软件实现。这种加密算法是美国联邦政府采用的区块加密标准,这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。
首先AES和DES一样,都是对称加密编码方式。 AES支持3种密码长度:128位、192位和256位,分组大小为128位的分组密码,在软件和硬件上实现效率都很高。DES在软件上实现效率比AES低。 分组密码的基本设计思想,包括混淆和扩散,DES和AES都有这重要属性。 混淆:是一种使密钥与密文之间的关系尽可能模糊的加密操作。 扩散:是一种为了隐藏明文的统计属性而将一个明文符号的影响扩散到多个密文符号的加密操作。如位置换。
AES密钥长度不一样,密码内部轮的数量也不一样,128位时10轮,192位时12轮,256位时14轮。用行数或列数来分:数据块长度除以32(4行4字节32位),分别是4,6,8。数据块长度和密钥长度相等的。加解密的过程如下图所示。
AES简介可以参考下面的地址,讲的非常详细! http://www.mamicode.com/info-detail-514466.html 看完上面文章,我们可以得出子密钥的个数为轮数+1。 上图是我在实际项目中使用AES256加密时的aes_key,密钥为256为的AES拥有32个字节,14轮,因此有15个子密钥 ,每个子密钥存放了60个单词,分别存放在60个单词的数组中。这就是上图看到的!
分组密码的几种操作模式:
上面各种模式的介绍网上也一大堆了,看完后也许不是非常懂,可能需要用过后才能更深理解。 在iOS中我们一般默认选择ECB模式,还有常用的CBC模式, ECB和CFB两种模式有个共同点:加密时如果原文的长度不是组长的整数倍,需要填充,如原文长度是34个字节,34%16 = 2,需要在原文后面追加14字节长度的空字符串(用0填充)。同理解密时的密文长度也必须是16字节的整数倍。
CBC模式 NoPadding 加密时如果原文的长度不是组长的整数倍,需要填充 存在Padding时 可以不填充 我们app都是填充的
算法/模式/填充 | 16字节加密后数据长度 | 不满16字节加密后长度 |
---|---|---|
AES/CBC/NoPadding | 16 | 不支持 |
AES/CBC/PKCS5Padding | 32 | 16 |
AES/CBC/ISO10126Padding | 32 | 16 |
AES/CFB/NoPadding | 16 | 原始数据长度 |
AES/CFB/PKCS5Padding | 32 | 16 |
AES/CFB/ISO10126Padding | 32 | 16 |
AES/ECB/NoPadding | 16 | 不支持 |
AES/ECB/PKCS5Padding | 32 | 16 |
AES/ECB/ISO10126Padding | 32 | 16 |
AES/OFB/NoPadding | 16 | 原始数据长度 |
AES/OFB/PKCS5Padding | 32 | 16 |
AES/OFB/ISO10126Padding | 32 | 16 |
AES/PCBC/NoPadding | 16 | 不支持 |
AES/PCBC/PKCS5Padding | 32 | 16 |
AES/PCBC/ISO10126Padding | 32 | 16 |
以上是来之网上的数据,经实践AES/CBC/NoPadding 和AES/CBC/PKCS7Padding 和上面描述的一致。
if(dataLength%kCCBlockSizeAES128 !=0)
{
NSMutableData* selfdata=[self mutableCopy];
int leftlen=kCCBlockSizeAES128-dataLength%kCCBlockSizeAES128;
char padddata[kCCBlockSizeAES128];
memset(padddata,0,kCCBlockSizeAES128);//将padddata都置为0
[selfdata appendBytes:padddata length:leftlen];
rawbytes=[selfdata bytes];
dataLength +=leftlen;
}
重要函数
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,/*dataOut缓冲区的大小,如果指定填充模式PKCS7 需要增加一个块的长度kCCAlgorithmAES128*/
size_t *dataOutMoved) /*结果的字节数写入dataOut*/
CBC和CFB模式下会有iv初始化向量的使用,可自己定义这个值,但iOS中有说明必须和选择算法的块长度保持一致。其他模式,这个值只需传入NULL就可以了。
在github上写了一个iOS加密例子:https://github.com/weskhen/TestForAES
总结:iOS应用中AES加密还是比较常用的,因为在软件上它的性价比高于其他一般的加密算法。但加密学这技术太深了,有好多东西还是没有理解,可能有些知识还理解错了,还是要继续去挖掘。
###ECC加密算法
椭圆加密算法(ECC)也是一种公钥加密体制,ECC与RSA和DSA的安全性对比 椭圆曲线密码体制的安全性基于椭圆曲线上离散对数问题的困难性,即公钥Q=dp求 出私钥d的数学困难问题。一般认为,椭圆曲线上的离散对数问题是比大整数因式分解和 有限域上离散对数更困难的问题。 同时,椭圆曲线公钥系统(ECC)所需要的密钥较短。在相同的安全级别上,ECC 所需的密钥长度比RSA和DSA系统需要的密钥长度更短。
ECC、RSA和DSA的安全性分析,如下图所示。
当前,一般认为破译时间为1012 MIPS年代表安全。为此,RSA和DSA要求密钥长 为1024比特,而160比特对于ECC就已经足够了;且当密钥加长时,ECC的安全性比 RSA和DSA增加快的多。如240比特密钥长的ECC就比2048比特密钥长的RSA和DSA 安全,虽然此时RSA和DSA从1024比特增加到2048比特,而ECC只是从160比特增 加到240比特。
安全性高 有研究表示160位的椭圆密钥与1024位的RSA密钥安全性相同。
加密效率比较
1)计算负荷:在私钥的加密解密速度上,速度更快。
2)密钥大小:存储空间占用小。
3)带宽:带宽要求低.
###AES和ECC混合加密
AES的Key经过接收方公钥加密和AES加密的内容 一起发送给接收方,接收方通过自己私钥先将加密后的AES_KEY解密,再通过解密得到的原始AES_KEY,并用该key解密发送方发送的内容,得到明文。 如下图所示:
一般的AES和ECC混合加密是上面流程的,但是我们app采用了另外一种加密方式: 对方的ECC公钥和自己的ECC私钥 得到一个相同的AES密钥Key
解释:
由ECC(椭圆曲线加密)数学函数 Q=dG; (Q是公钥 d是私钥 G是他们之间的关系)
Q1=d1G1; Q2=d2G2; 那个可以推出 AES的key=Q1d2G2 = Q2d1G1;
unsigned char share_key[ECC_KEY_BYTES];//指定32位
crypto_scalarmult(share_key, private_key, peer_public_key);//生成对应的AES key
流程图如下:
方式二的优势:不需要把暴露AES秘钥暴露给对方,双发只要知道对方的公钥就可以完成高安全性的加密方式。
来源:oschina
链接:https://my.oschina.net/u/1391235/blog/791142