C与C#通讯加密之C语言DES的cbc pkcs7的实现(二)

没有想到,上个随笔的代码在POS机上出错,查了半天,如果去掉malloc和free,就没有事了。
所以,把现在的不用动态内存分配的算法记录下

ExpandedBlockStart.gif ContractedBlock.gif /**/ /*
InBlock.gif    功能:用mode = cbc , padding = pkcs7 来加密
InBlock.gif         如果to == NULL, 则返回加密后数据的长度
InBlock.gif    书写:evlon ,QQ:273352165
ExpandedBlockEnd.gif
*/

None.gif
int  des_cbc_pkcs7_encrypt(uchar *  from,  int  nLength,  uchar  *  to, uchar key[],uchar iv[])
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
//uchar buffer[8];
InBlock.gif
    int nSize = nLength % 8 ?(nLength + 7/ 8 * 8 : nLength + 8;
InBlock.gif    
if(to == NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
//计算长度
InBlock.gif
        return nSize;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        deskey(key,EN0);
InBlock.gif        uchar preEnc[
8];
InBlock.gif        memcpy(preEnc,iv,
8);
InBlock.gif        
InBlock.gif        
//加密块
InBlock.gif
        int i=0;
InBlock.gif        
for(; i < nSize; i+=8)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            uchar
*     ps = from + i;
InBlock.gif            uchar
*     pd = to + i;
InBlock.gif
InBlock.gif            
if(nSize - i > 8)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//XOR
InBlock.gif
                for(int j = 0; j < 8++j)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    preEnc[j] 
^= *(ps + j);
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//XOR
InBlock.gif
                for(int j = 0; j < nLength - i; ++j)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    preEnc[j] 
^= *(ps + j);
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
for(int j = nLength - i; j < 8++j)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    preEnc[j] 
^= nSize - nLength;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            des(preEnc,pd);
InBlock.gif
InBlock.gif            
//保存前一个输出
InBlock.gif
            memcpy(preEnc, pd,8);
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif        
return i;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
None.gif
int  des_cbc_pkcs7_decrypt(uchar *  from,  int  nLength,  uchar  *  to, uchar key[], uchar iv[])
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
InBlock.gif    
if(nLength % 8)
InBlock.gif        
return 0;    //数据不正确
InBlock.gif
InBlock.gif
InBlock.gif    
//uchar* toBackup = to;
InBlock.gif    
//to = (uchar*)malloc(nLength);    //申请内存
InBlock.gif
InBlock.gif    
//XOR
InBlock.gif
    uchar preEnc[8],buffer[8];
InBlock.gif    memcpy(preEnc,iv,
8);
InBlock.gif
InBlock.gif    deskey(key,DE1);
InBlock.gif
InBlock.gif    
int i = 0;
InBlock.gif    
for(; i < nLength; i+=8)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        uchar
*     ps = from + i;
InBlock.gif        uchar
*     pd = to + i;
InBlock.gif
InBlock.gif        des(ps,buffer);
InBlock.gif
InBlock.gif        
//XOR
InBlock.gif
        for(int j = 0; j < 8++j)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            buffer[j] 
^= preEnc[j];
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif
InBlock.gif        
if(nLength - i > 8)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//保存前一个输出
InBlock.gif
            memcpy(preEnc, ps,8);
InBlock.gif            memcpy(pd,buffer,
sizeof(buffer));
ExpandedSubBlockEnd.gif        }

InBlock.gif        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//去除数据尾
InBlock.gif
            uchar chEnd = buffer[sizeof(buffer) - 1];
InBlock.gif            
if(chEnd > 0 && chEnd < 9)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//有可能是填充字符,去除掉
InBlock.gif
                for(int j = sizeof(buffer) - 1; j >= (int)(sizeof(buffer) - chEnd); --j)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
if(buffer[j] != chEnd)
InBlock.gif                        
return 0;
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
int nSize =nLength - chEnd;
InBlock.gif
InBlock.gif                memcpy(pd, buffer, 
sizeof(buffer) - chEnd);
InBlock.gif                
InBlock.gif                
return nLength - chEnd;
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//数据格式不正确
InBlock.gif
                return 0;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
return 0;
ExpandedBlockEnd.gif}

None.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
面向工程应用:市面上的一些密码学课程和密码学的书籍,很多都是从考证出发,讲解算法原理并不面向工程应用,而我们现在缺少的是工程应用相关的知识,本课程从工程应用出发,每种技术都主要讲解其在工程中的使用,并演示工程应用的代码。 从零实现部分算法: 课程中实现了base16编解码 ,XOR对称加解密算法,PKCS7 pading数据填充算法,通过对一些简单算法的实现,从而加深对密码学的理解。理论与实践结合: 课程如果只是讲代码,同学并不能理解接口背后的原理,在项目设计中就会留下隐患,出现错误也不容易排查出问题。如果只讲理论,比如对密码学的一些研究,对于大部分从事工程应用的同学并没有必要,而是理论与实践结合,一切为了工程实践。代码现场打出: 代码不放在ppt而是现场打出,更好的让学员理解代码编写的逻辑,老师现场敲出代码正是展示出了工程项目的思考,每个步骤为什么要这么做,考虑了哪些异常,易学不枯燥: 课程为了确保大部分人开发者都学得会,理解算法原理(才能真正理解算法特性),学会工程应用(接口调用,但不局限接口调用,理解接口背后的机制,并能解决工程中会出现的问题),阅读算法源码但不实现密码算法,,并能将密码学投入到实际工程中,如果是想学习具体的加密算法实现,请关注我后面的课程。
AES/CBC/PKCS7Padding是一种常用的加密算法,可用于对数据进行保护。在C语言中,可以通过使用OpenSSL库来实现该算法。 下面是一个使用AES/CBC/PKCS7Padding加密算法的示例代码: ```c #include <openssl/aes.h> #include <openssl/rand.h> #define AES_BLOCK_SIZE 16 void encrypt(const unsigned char *plaintext, int plaintext_len, const unsigned char *key, const unsigned char *iv, unsigned char *ciphertext) { AES_KEY aesKey; AES_set_encrypt_key(key, 128, &aesKey); AES_cbc_encrypt(plaintext, ciphertext, plaintext_len, &aesKey, iv, AES_ENCRYPT); } void decrypt(const unsigned char *ciphertext, int ciphertext_len, const unsigned char *key, const unsigned char *iv, unsigned char *plaintext) { AES_KEY aesKey; AES_set_decrypt_key(key, 128, &aesKey); AES_cbc_encrypt(ciphertext, plaintext, ciphertext_len, &aesKey, iv, AES_DECRYPT); } int main() { unsigned char key[AES_BLOCK_SIZE] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; unsigned char iv[AES_BLOCK_SIZE]; unsigned char plaintext[32] = "Hello, AES/CBC/PKCS7Padding"; unsigned char ciphertext[sizeof(plaintext)]; unsigned char decryptedtext[sizeof(plaintext)]; RAND_bytes(iv, sizeof(iv)); encrypt(plaintext, sizeof(plaintext), key, iv, ciphertext); decrypt(ciphertext, sizeof(ciphertext), key, iv, decryptedtext); printf("Original Text: %s\n", plaintext); printf("Encrypted Text: %s\n", ciphertext); printf("Decrypted Text: %s\n", decryptedtext); return 0; } ``` 以上代码使用了OpenSSL库中的AES函数,分别实现加密和解密的功能。主函数中生成了一个16字节的密钥和随机生成的16字节初始化向量。然后将明文进行加密,并将密文进行解密,最后打印出原始文本、加密文本和解密文本。 需要注意的是,加密后生成的密文长度要比原始明文长度稍长,因此ciphertext的长度使用了sizeof(plaintext)。为了避免截断问题,推荐使用静态大小的缓冲区来存储密文。 这只是一个简单的示例,实际应用中还需考虑安全性、密钥管理等因素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值