亚洲必赢手机入口【加密解密】加密解密介绍 .NET中的DES对如加密。

by admin on 2018年10月5日

DES是同一种对如加密(Data Encryption
Standard)算法,于1977年赢得美国政府之正经认可,是一律种植用56各项密钥来加密64各项数据的措施。一般密码长度也8独字节,其中56个加密密钥,每个第8员都看成奇偶校验。

参考文章

  • Base64

  • Base64编码/解码

  • 填充算法,mac与java的分

  • 片密码的劳作模式

  • 分组密码

  • PKCS


DES算法一般生少个基本点点,第一个凡是加密模式,第二单凡是数量补位,加密模式之严重性意义就是是,加密算法是依照块进行加密的,例如
DES ,是 64Bit 一个片的拓展加密,就是每次加密 8
只字节,因此老是输入八独字节的公然输出八独字节密文,如果是 16
个字节,那么分成两单片依次进行加密,问题即使涌出于此间,如果公开是
1234567812345678,分块分别开展加密,那么加密的结果类似“C4132737962C519C
C4132737962C519C”,可以望明文的规律,这就是是 ECB
加密模式,密文可以见到明文的原理;为了缓解是题材,有矣别的加密模式:CBC
加密模式(密码分组连接),CFB加密模式(密码反馈模式),OFB加密模式(输出反馈模式)CBC
是要求吃一个初始化的通向量,然后以每个输出以及该向量作运算,并以运算的结果当下一个加密块的初始化向量,CFB
和 OFB
则未待提供初始化向量,直接以密码或输出作为初始化向量进行演算;这样即便避免了堂而皇之的原理起在密文中;当然缺点是解密时得保证密文的正确性,如果网络传输时发了一致片错误,则后面的解密结果就是可能是错误的;(ECB模式仅影响传输错误的不胜块。密码算法基本上都是分组(按快)进行加密的,如果密文长度不是正好得拓展分组,怎么惩罚?只能进行填。

Base64编码

据我说知,苹果并没有提供API来是实现Base64编码,所以需要看官在网上寻找验证,还好,这并不难

感谢Lonely__和angelababa的提醒,苹果是发Base64的API,截图如下:

苹果提供Base64API.png

Base64编码的思是凡动64个基本的ASCII码字符对数据进行重新编码。它将急需编码的数目拆分成字节数组。以3个字节否平组。按顺序排列24 位数据,再管这24各数据分为4组,即每组6位。再于每组的之最高位前补两个0凑足一个字节。这样就把一个3字节为一组的数据重新编码成了4个字节。当所假设编码的数的字节数不是3底整倍数,也就是说在分组时最终一组不敷3个字节。这时在最后一组填充1到2只0字节。并于最终编码完成后以终极添加1到2独
“=”。

例:将对ABC进行BASE64编码:

1、首先取ABC对应的ASCII码值。A(65)B(66)C(67);

2、再取得二前行制值A(01000001)B(01000010)C(01000011);

3、然后将当时三独字节的二进制码接起(010000010100001001000011);

4、
再因6位呢单位分为4独数据块,并当高高的位填充两个0后形成4个字节的编码后的价,(00010000)(00010100)(00001001)(00000011),其中加色部分也真实数据;

5、再将当时四单字节数据转发成为10迈入制数得(16)(20)(9)(3);

6、最后根据BASE64给有的64单主导字符表,查出对应之ASCII码字符(Q)(U)(J)(D),这里的值实际就是是数额以字符表中之目录。

Base64编码表

解码过程尽管是管4独字节再还原成3个字节再冲不同之数据形式拿字节数组重新整理成多少。

Base64很直观的目的就是是受二进制文件转发为64个为主的ASCII码字符。

加密算法常见的有ECB模式与CBC模式:
第一栽电子密本方式(ECB) 
     
ECB模式:电子密本方式,就是拿数据论8独字节一段子展开DES加密或解密得到相同截8单字节的密文或者明文,最后一段不足8只字节,则补足8独字节(注意:这里虽事关到多少补位了)进行测算,之后仍顺序以计所得之多少连在一起即可,各段数据里面互不影响。将公开分成n个64较单分组,如果公开长度不是64于仅的倍数,则在明文末尾填充适当数目的确定符号。对明文组用给定的密钥分别开展加密,行密文C=(C0,C1,……,Cn-1)其中Ci=DES(K,xi),i=0,1,…..,n-1。
这是Java封装的DES算法的默认模式.
仲栽密文分组链接方式(CBC)  

AES

系吧并无一直提供诸如DES、AES的API,但是提供了加密解密的相关操作CommonCrypto,DES或者AES的实现,需要我们团结包装一下。

加密凡由于算法/模式/填充整合的,算法是DES,AES等,
模式是EBC,CBC等,iOS和Android的填是不雷同的:

mac支持:

NoPadding (NoPadding就是匪填充,相当给由定义填充)

PKCS7Padding

而java支持:

NoPadding

ISO10126Padding

OAEPPadding, OAEPWith<digest>And<mgf>Padding

PKCS1Padding

PKCS5Padding

SSL3Padding

通下去我们引入一些背景知识:

每当密码学中,分组加密(Block
cipher,又如分块加密),是同样栽对称密钥算法。它将公开分成多单相当丰富的模块(block),使用规定的算法和针对性如密钥对每组分别加密解密。分组加密是极其重要的加密协议组成,其中突出的如DES和AES作为美国政府裁决的专业加密算法,应用领域从电子邮件加密到银行贸易转帐,非常广泛。

密码学中的工作模式:

最为早出现的干活模式,ECB,CBC,OFB和CFB可以追溯到1981年。2001年,NIST修订了那个原先发布之做事模式工作列表,加入了AES,并加入了CTR模式。最后,在2010年1月,NIST加入了XTS-AES,而另的可信模式并从未也NIST所认证。例如CTS是平等种植密文窃取的模式,许多广大的密码学运行库提供了这种模式。

密码学中,块密码的干活模式允许使用和一个片密码密钥对多于一块的多少进行加密,并确保其安全性。块密码自身只能加密长度等密码片长的单块数据,若一旦加密变长数据,则数要先行让分开为局部独自的密码块。通常而言,最后一块数据也急需动用方便填充方式拿数据扩展至适合密码片大小的长短。一栽工作模式描述了加密每一样数据块的长河,并常用基于一个一般性称为初始化向量的附加输入值为进行随机化,以保证安全。

初始化向量

初始化向量(IV,Initialization
Vector)是累累工作模式受到用于随机化加密的一致片数据,因此得以由同样之明,相同的密钥产生不同的密文,而随便需另行发密钥,避免了日常相当复杂的立刻同进程。

初始化向量与密钥相比来异之安全性要求,因此IV通常并非保密,然而以大部分动静中,不应有在采用同样密钥的景象下零星涂鸦使用以及一个IV。对于CBC和CFB,重用IV会导致泄露明文首单片的一点信息,亦包括个别独例外消息被同样的前缀。对于OFB和CTR而言,重用IV会导致全盘失去安全性。另外,在CBC模式被,IV在加密常必是心有余而力不足预测的;特别的,在许多落实着采取的发IV的法门,例如SSL2.0运用的,即以上一个消息的结尾一片密文作为下一个信之IV,是休安全之。

留神:ECB模式不需初始化向量,之所以提一词,是以自于是的ECB模式。

填充

片密码只能针对规定长度的数块进行处理,而消息的尺寸一般是可变的。因此片模式(即ECB和CBC)需要最后一片当加密前开展填空。有数种填充方法,其中最简便易行的平种植是以平文的末段填充空字符以要其尺寸为片长的平头倍增,但要保证可以回复平文的原始长度;例如,若平文是C语言风格的字符串,则只是出失误尾会有空字符。稍微复杂一点之主意则是原本的DES使用的法门,即以数额后补充加一个1位,再上加足够的0位直到满足块长的求;若消息长度刚好符合块长,则增长一个填写充块。最复杂的尽管是对CBC的措施,例如密文窃取,残块终结等,不会见来额外的密文,但会追加有复杂度。布鲁斯·施奈尔以及尼尔斯·弗格森提出了少于栽简单的可能性:添加一个价值吗128之字节(十六进制的80),再为0字节填写满最后一个片;或于终极一个块填充n个值均为n的字节。

CFB,OFB和CTR模式不需对长不呢密码片大小整数加倍的信进行专门之处理。因为这些模式是经对块密码的输出和平文进行异或工作之。最后一个平文块(可能是不整的)与密钥流块的前面几个字节异或后,产生了和该平文块大小同等之密文块。流密码的之特性使得它可以动用在待密文和平文数据长严格等的场所,也足以以在为流动式传输数据而非便宜进行填的场子。

顾:ECB模式是内需填写的。

ECB:
顶简便的加密模式就是为电子密码本(Electronic
codebook,ECB)模式。需要加密的信息据块密码的片大小为分成数只片,并对准每个片进行单独加密。

ECB加密

ECB解密

遵办法的通病在于同的平文块会吃加密成相同的密文块;因此,它不克可怜好之隐蔽数据模式。在好几场合,这种方式无能够提供严格的数量保密性,因此并无推荐用于密码协议中。下面的事例显示了ECB在密文中展示平文的模式之档次:该图像的一个位图版本(上图)通过ECB模式也许会见于加密成中图,而非ECB模式通常会拿其加密成极下图。

原图

动用ECB模式加密

供了伪随机性的非ECB模式

原图是应用CBC,CTR或外其它的重新安全之模式加密最下图或发生的结果——与随机噪声无异。注意最下图看起的随机性并无能够代表图像已经于安全的加密;许多无安全的加密法也说不定发这种“随机的”输出。

ECB模式也会见造成使用它的协议不可知提供数据完整性保护,易受到重放攻击的影响,因此每个片是以完全相同的方解密的。例如,“梦幻的星在线:蓝色脉冲”在线电子游戏使用ECB模式的Blowfish密码。在密钥交换系统受破解而发出重复简便易行的破解方式前,作弊者重复通过发送加密的“杀死怪物”消息包以非官方的长足增加阅历值。

另模式于这就是不进行了,详情请转片密码的工作模式
,进一步询问CBC、CFB、OFB、CTR等模式。

管极重大之函数摘出来解释一下:

/*!
    @function   CCCrypt
    @abstract   Stateless, one-shot encrypt or decrypt operation.
                This basically performs a sequence of CCCrytorCreate(),
                CCCryptorUpdate(), CCCryptorFinal(), and CCCryptorRelease().

    @param      alg             Defines the encryption algorithm.


    @param      op              Defines the basic operation: kCCEncrypt or
                    kCCDecrypt.

    @param      options         A word of flags defining options. See discussion
                                for the CCOptions type.

    @param      key             Raw key material, length keyLength bytes. 

    @param      keyLength       Length of key material. Must be appropriate 
                                for the select algorithm. Some algorithms may 
                                provide for varying key lengths.

    @param      iv              Initialization vector, optional. Used for 
                                Cipher Block Chaining (CBC) mode. If present, 
                                must be the same length as the selected 
                                algorithm's block size. If CBC mode is
                                selected (by the absence of any mode bits in 
                                the options flags) and no IV is present, a 
                                NULL (all zeroes) IV will be used. This is 
                                ignored if ECB mode is used or if a stream 
                                cipher algorithm is selected. 

    @param      dataIn          Data to encrypt or decrypt, length dataInLength 
                                bytes. 

    @param      dataInLength    Length of data to encrypt or decrypt.

    @param      dataOut         Result is written here. Allocated by caller. 
                                Encryption and decryption can be performed
                                "in-place", with the same buffer used for 
                                input and output. 

    @param      dataOutAvailable The size of the dataOut buffer in bytes.  

    @param      dataOutMoved    On successful return, the number of bytes
                    written to dataOut. If kCCBufferTooSmall is
                returned as a result of insufficient buffer
                space being provided, the required buffer space
                is returned here. 

    @result     kCCBufferTooSmall indicates insufficent space in the dataOut
                                buffer. In this case, the *dataOutMoved 
                                parameter will indicate the size of the buffer
                                needed to complete the operation. The 
                                operation can be retried with minimal runtime 
                                penalty. 
                kCCAlignmentError indicates that dataInLength was not properly 
                                aligned. This can only be returned for block 
                                ciphers, and then only when decrypting or when 
                                encrypting with block with padding disabled. 
                kCCDecodeError  Indicates improperly formatted ciphertext or
                                a "wrong key" error; occurs only during decrypt
                                operations. 
 */  

CCCryptorStatus CCCrypt(
    CCOperation op,         /* 枚举值,确认是加密操作,还是解密操作 */
    CCAlgorithm alg,        /* 枚举值,确认加解密的算法,如kCCAlgorithmAES128、kCCAlgorithmDES */
    CCOptions options,      /* 枚举值,kCCOptionPKCS7Padding | kCCOptionECBMode,经我调查,这样就是ECB模式,并以PKCS7来填充*/
    const void *key,
    size_t keyLength,
    const void *iv,         /* 初始化向量(NULLoptional initialization vector),ECB模式写NULL就行 */
    const void *dataIn,     /* optional per op and alg */
    size_t dataInLength,
    void *dataOut,          /* data RETURNED here */
    size_t dataOutAvailable,
    size_t *dataOutMoved)  

地方说交,iOS和Android填充是未相同的,那怎么收拾?据说,PKCS7Padding是兼容PKCS5Padding的,我以跟安卓同测试中,确实尚未问题。

管自为此底AES加密摘出来吧:

自家因此之凡一个NSData类目NSData+AES,密钥是128员之,即16只字节,加密解密方法的落实如下(记得引#import <CommonCrypto/CommonCryptor.h>):

加密:

- (NSData *)AES128EncryptWithKey:(NSString *)key
{
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [self length];

    //See the doc: For block ciphers, the output size will always be less than or
    //equal to the input size plus the size of one block.
    //That's why we need to add the size of one block here
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          keyPtr, kCCKeySizeAES128,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }

    free(buffer); //free the buffer;
    return nil;
}  

解密:

- (NSData *)AES128DecryptWithKey:(NSString *)key {
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [self length];

    //See the doc: For block ciphers, the output size will always be less than or
    //equal to the input size plus the size of one block.
    //That's why we need to add the size of one block here
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding| kCCOptionECBMode,
                                          keyPtr, kCCKeySizeAES128,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesDecrypted);

    if (cryptStatus == kCCSuccess) {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }

    free(buffer); //free the buffer;
    return nil;
}  

     
密文分组链接道,在CBC方式下,每个明文组xi在加密前跟事先一组密文按位模二加后,再送及DES加密,CBC方式克服了ECB方式报内组重的毛病,但由明文组加密前以及平组密文有关,因此前一组密文的错会传到下一致组。
这是.NET封装的DES算法的默认模式,它于辛苦,加密步骤如下:

1、首先用数据论8个字节一组进行分组得到D1D2……Dn(若数据未是8底整数倍增,就关乎到数量补位了)

2、第一组数D1与向量I异或后底结果进行DES加密得到第一组密文C1(注意:这里发生向量I的传教,ECB模式下并未运用于量I)

3、第二组数D2与第一组的加密结果C1异或以后的结果开展DES加密,得到第二组密文C2

4、之后的数额因此类推,得到Cn

5、按梯次并也C1C2C3……Cn即为加密结果。

老三种密文反馈方式(CFB),可用以序列密码
   明文X=(x0,x1,……,xn-1),其中xi由t个比较特组成0  
第四栽输出反馈方式(OFB),可用于序列密码
  
与CFB唯一不同的凡OFB是直接取DES输出的t个比特,而未是取密文的t个比特,其余都跟CFB相同。但它得到的凡DES的出口,所以她克服了CFB的密文错误传播之欠缺

数补位一般生NoPadding和PKCS7Padding(Java中凡PKCS5Padding)填充方式,PKCS7Padding和PKCS5Padding实际只是商量不同等,根据有关材料证实:PKCS5Padding明确定义了加密片是8字节,PKCS7Padding加密快好是1-255以内。但是封装的DES算法默认都是8字节,所以可以看她们一致。数据补位实际是当数码不满8字节的翻番,才上及8字节的倍数的填写过程。

NoPadding填充方式:算法本身不填充,比如.NET的padding提供了起None,Zeros方式,分别吗不填和填充0的章程。

PKCS7Padding(PKCS5Padding)填充方式:为.NET和Java的默认填充方式,对加密数量字节长度对8取余为r,如r大于0,则补8-r独字节,字节为8-r底值;如果r等于0,则上8个字节8.比如:

加密字符串为也AAA,则补位为AAA55555;加密字符串为BBBBBB,则补位为BBBBBB22;加密字符串为CCCCCCCC,则补位为CCCCCCCC88888888.

.NET中的DES加密

对于.NET,框架在System.Security.Cryptography命名空间下提供了DESCryptoServiceProvider作为System.Security.Cryptography.DES加密解密之卷入接口,它提供了如下的4单道:

public override ICryptoTransform CreateDecryptor(byte[] rgbKey,
byte[] rgbIV)

public override ICryptoTransform CreateEncryptor(byte[] rgbKey,
byte[] rgbIV)

public override void GenerateIV()

public override void GenerateKey()

从.NET接近库封装情况,加解密需要传入一个Key和IV向量。而且Key必须为8字节底多少,否则会一直丢掉大出,当使用ECB模式下,不管传入什么IV向量,加密结果都同一。

 

各大语言互操作解决方案:

  • C与C#简报加密之C语言DES的cbc
    pkcs7的落实
  • C与C#报道加密之C语言DES的cbc
    pkcs7的兑现(二)
  • python和c#通用一致的des加密应用CBC和PKCS7
  • php实现3DES加密算法,工作模式CBC,填充模式PKCS7
    Padding
  • 用 Java 解密 C#
    加密的数(DES)
  • Applied Crypto++: Block
    Ciphers 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图