开发环境:ubuntu 12.04 i386
程序功能: 从文件src 加密到文件dec,加密方式用3des
问题描述: EVP_des_ede3_ecb() 会出现自动填充
源码文件:
1 /* 2 *author:Xin 3 *date:2015/12/2 4 *func:文件加解密 5 */ 6 #include <stdio.h> 7 #include <string.h> 8 #include <unistd.h> 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 #include <openssl/evp.h> 13 14 /* 15 * 加密接口 16 * indata输入数据 indatalen输入数据长度 17 * outdata输出数据 outdatalen输出数据长度 18 */ 19 int encrypt(unsigned char *indata, int indatalen, unsigned char *outdata, int *outdatalen) { 20 21 unsigned char key[EVP_MAX_KEY_LENGTH]; //秘钥key 22 unsigned char iv[EVP_MAX_KEY_LENGTH]; //向量iv 23 int tmplen; 24 int i; 25 EVP_CIPHER_CTX ctx; //EVP算法上下文 26 EVP_CIPHER_CTX_init(&ctx); //初始化密码算法结构体 27 28 for (i = 0; i<16; i++) //初始化秘钥key 29 key[i] = i; 30 for (i = 0; i<8; i++) //初始化向量iv 31 iv[i] = i; 32 //设置算法和秘钥以及初始化向量 33 if (EVP_EncryptInit_ex(&ctx, EVP_des_ede3_ecb(), NULL, key, iv) != 1) { 34 printf("EVP_EncryptInit_ex failed\n"); 35 return 1; 36 } 37 //EVP_CIPHER_CTX_set_padding(&ctx, 0); 38 //数据加密 39 if (EVP_EncryptUpdate(&ctx, outdata, outdatalen, indata, indatalen) != 1) { 40 printf("EVP_EncryptUpdate failed\n"); 41 return 2; 42 } 43 //结束数据加密,把剩余数据输出 44 if (EVP_EncryptFinal_ex(&ctx, outdata + *outdatalen, &tmplen) != 1) { 45 printf("Evp_EncryptFinal_ex failed\n"); 46 return 3; 47 } 48 49 *outdatalen += tmplen; 50 //打印加密后的长度 51 printf("outdatalen: %d\n", *outdatalen); 52 53 return 0; 54 } 55 56 /* 57 * 加密接口 58 * indata输入数据 indatalen输入数据长度 59 * outdata输出数据 outdatalen输出数据长度 60 */ 61 int decrypt(unsigned char *indata, int indatalen, unsigned char *outdata, int *outdatalen) 62 { 63 unsigned char key[EVP_MAX_KEY_LENGTH]; //秘钥key 64 unsigned char iv[EVP_MAX_KEY_LENGTH]; //向量iv 65 int i; 66 int tmplen; 67 EVP_CIPHER_CTX ctx; //EVP算法上下文 68 EVP_CIPHER_CTX_init(&ctx); //初始化密码算法结构体 69 70 //EVP_CIPHER_CTX_set_padding(&ctx, 0); 71 for (i = 0; i<16; i++) { 72 key[i] = i; 73 } 74 for (i = 0; i<8; i++) { 75 iv[i] = i; 76 } 77 //设置算法和秘钥以及初始化向量 78 if (EVP_DecryptInit_ex(&ctx, EVP_des_ede_ecb(), NULL, key, iv) != 1) { 79 printf("EVP_DecryptInit_ex fail\n"); 80 return 1; 81 } 82 //数据解密 83 if (EVP_DecryptUpdate(&ctx, outdata, outdatalen, indata, indatalen) != 1) { 84 printf("EVP_DecryptUpdate fail\n"); 85 return 2; 86 } 87 88 //结束数据解密,把剩余数据输出 89 if (EVP_DecryptFinal_ex(&ctx, outdata + *outdatalen, &tmplen) != 1) { 90 printf("EVP_DecryptFinal_ex fail\n"); 91 return 3; 92 } 93 94 *outdatalen += tmplen; 95 96 return 0; 97 } 98 /* 99 *myecrypt 文件加密接口 100 *src读取文件 dec加密后的文件 101 */ 102 int myencrypt(char *src, char *dec) 103 { 104 int sfd, dfd; 105 unsigned char buf[1024]; 106 unsigned char buftmp[2048]; 107 int buftmplen; 108 int rlen; 109 110 sfd = open(src, O_RDONLY); 111 printf("sfd = %d\n", sfd); 112 if (sfd == -1) { 113 printf("sfd open:"); 114 return 1; 115 } 116 117 dfd = open(dec, O_WRONLY|O_CREAT|O_TRUNC , 0777); 118 printf("dfd = %d\n", dfd); 119 if (dfd == -1) { 120 printf("des open failed\n"); 121 close(sfd); 122 return 2; 123 } 124 125 while ((rlen = read(sfd, buf, 1024)) > 0) { 126 printf("rlen:%d\n", rlen); 127 if (en(buf, rlen, buftmp, &buftmplen) == 0) { 128 write(dfd, buftmp, buftmplen); 129 } else { 130 close(dfd); 131 close(sfd); 132 return 3; 133 } 134 } 135 close(dfd); 136 close(sfd); 137 return 0; 138 139 } 140 /* 141 * mydecrypt 文件解密接口 142 * src 读取的文件 dec 解密后的文件 143 * 144 */ 145 int mydecrypt(char *src, char *dec) 146 { 147 int sfd, dfd; 148 unsigned char buf[1032]; 149 unsigned char tmpbuf[2048]; 150 int buflen; 151 int tmpbuflen; 152 153 sfd = open(src, O_RDONLY); 154 if (sfd == -1) { 155 printf("sfd open failed\n"); 156 return 1; 157 } 158 159 dfd = open(dec, O_WRONLY | O_CREAT| O_TRUNC, 0644); 160 if (dfd == -1) { 161 close(sfd); 162 printf("dfd open failed\n"); 163 return 2; 164 } 165 166 while ((buflen = read(sfd, buf, 1032)) > 0) { 167 printf("buflen: %d\n", buflen); 168 if (de(buf, buflen, tmpbuf, &tmpbuflen) == 0) { 169 write(dfd, (char *)tmpbuf, tmpbuflen); 170 } else { 171 close(sfd); 172 close(dfd); 173 } 174 } 175 176 close(sfd); 177 close(dfd); 178 return 0; 179 } 180 181 int main(int argc, char *argv[]) 182 { 183 if (argc < 4) { 184 printf("./myende plain enctxt dectxt"); 185 exit(-1); 186 } 187 188 if(myencrypt(argv[1], argv[2]) != 0) 189 printf("文件加密失败"); 190 if(mydecrypt(argv[2], argv[3]) != 0) 191 printf("文件解密失败"); 192 return 0; 193 }
问题出现:在自己加密一个1024字节的数据时,竟然结果长度是1032
解决问题:openssl默认会自动填充,设置EVP_CIPHER_CTX_set_padding(&ctx,0); 1自动填充,0不填充
总结:这事与openssl机制有关系,他不会什么数据都会自动先问你填充,然后除8,如果除尽不填充,否则填充直到除尽为止