Пример #1
0
//AES/CBC/PKCS5Padding
//key只能是16、24、32个ASSCII字符组成的串儿
unsigned char* aes_cbc_pkcs5padding_decode(unsigned char *input, size_t inputLength, size_t *outputLength, const char *key) {
    size_t keyLength = strlen(key);
    printf("keyLength = %zu\n", keyLength);
    
    if (keyLength != 32 && keyLength != 24 && keyLength != 16) {
        perror("key必须是16、24、32个ASSCII字符组成的串\n");
        return NULL;
    }
    
    mbedtls_aes_context aes;
    
    //初始向量,一般是一个随机数组成的,长度必须是块大小,一个块是16字节,也就是16个ASCII字符
    unsigned char iv[16];
    memcpy(iv, key, keyLength);
    
    //解密后的数据长度
    unsigned char *output = (unsigned char *)calloc(inputLength, sizeof(unsigned char));
    
    //设置加密的key,并初始化
    mbedtls_aes_setkey_dec(&aes, (unsigned char*)key, keyLength * 8);
    
    //加密数据
    mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, inputLength, iv, input, output);
    
    int outputLastIndex = inputLength - 1;

    //取出output最后一个字节,转成数字
    unsigned int lastValue = output[outputLastIndex];
    printf("lastValue = %d\n", lastValue);
    if (lastValue > 0 && lastValue <= 16) {
        int j = outputLastIndex;
        while(output[j] == lastValue) {
            j--;
        }
        printf("j = %d\n", j);
        *outputLength = j + 1;
        outputLastIndex = j;
    }

    size_t inputHexLength = 2 * inputLength + 1;
    char inputHex[inputHexLength];
    memset(inputHex, 0, inputHexLength);
    bytes2HexStr(inputHex, input, inputLength);
    
    size_t outputHexLength = 2 * inputLength + 1;
    char outputHex[outputHexLength];
    memset(outputHex, 0, outputHexLength);
    bytes2HexStr(outputHex, output, inputLength);

    printf("aesDecode(%s, %s)=%s\n", inputHex, key, outputHex);
    
    return output;
}
Пример #2
0
/*
    加密, 带0填充   
    key--8字节密钥
    in--字符串(仅支持英文)或字节数组均可
    len--in的字节长度
    return--十六进制字符串, 外部使用后应free
*/
char * encrypt_str(unsigned char *key, char *in, int len)
{
    char *outStr = 0;
    char *buf = 0;
    char *p = 0;
    int fixedLen;
    int resident;
    int pos;

    resident = len % 8;
    if (resident == 0)
        fixedLen = len;
    else
        fixedLen = (len / 8 + 1) * 8;
    buf = (char *)malloc(fixedLen);
    memset(buf, 0, fixedLen);
    memcpy(buf, in, len);

    p = buf;
    pos = 0;
    
    /*init key*/
    deskey_jp(key, EN0);
    while(p < (buf+fixedLen)) {
        /*ECB encrypt*/
        des((unsigned char *)p, (unsigned char *)p);
        p = p + 8;
    }

    /*转化为十六进制字符串表示*/
    outStr = bytes2HexStr(buf, fixedLen);
    
    free(buf);

    return outStr;
    
}
Пример #3
0
//AES/CBC/PKCS5Padding
//input可以是任意长度
//key只能是16、24、32个ASSCII字符组成的串儿
unsigned char* aes_cbc_pkcs5padding_encode(const char *input, const char *key, size_t *outputLength) {
    size_t keyLength = strlen(key);
    printf("keyLength = %zu\n", keyLength);

    if (keyLength != 32 && keyLength != 24 && keyLength != 16) {
        perror("key必须是16、24、32个ASSCII字符组成的串\n");
        return NULL;
    }
        
    mbedtls_aes_context aes;

    //获取到输入的要加密的内容的长度
    size_t inputLength = strlen(input);
    printf("input = %s, inputLength = %zu\n", input, inputLength);

    //看看需要分成多少个块,即使输入的数据是16的整数倍,也要补充16个字节的整数16
    size_t n = inputLength / 16 + 1;

    //https://tools.ietf.org/html/rfc8018#appendix-B.2.5
    int padding = 16 - inputLength % 8;

    //用于加密的的数据长度:字节数,此字节数正好等于输出的字节数
    int needInputLength = 16 * n;
    *outputLength = needInputLength;

    //初始向量,一般是一个随机数组成的,长度必须是块大小,一个块是16字节,也就是16个ASCII字符
    unsigned char iv[16];
    memcpy(iv, key, keyLength);

    unsigned char *toBeEncryptBytes = (unsigned char *)calloc(needInputLength + 1, sizeof(unsigned char));
    memcpy(toBeEncryptBytes, (unsigned char *)input, inputLength);
    
    //填充数据
    for (int i = 0; i < padding; i++) {
        toBeEncryptBytes[inputLength + i] = padding;
    }
    toBeEncryptBytes[needInputLength] = '\0';

    //加密后的数据长度
    unsigned char *output = (unsigned char *)calloc(needInputLength, sizeof(unsigned char));

    //设置加密的key,并初始化
    mbedtls_aes_setkey_enc(&aes, (unsigned char*)key, keyLength * 8);

    //加密数据
    mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, needInputLength, iv, toBeEncryptBytes, output);
    
    char outputHex[ 2 * needInputLength + 1];
    memset(outputHex, 0, 2 * needInputLength + 1);

    bytes2HexStr(outputHex, output, needInputLength);

    printf("aesEncode(%s, %s)=%s\n", toBeEncryptBytes, key, outputHex);

    if (NULL != toBeEncryptBytes) {
        free(toBeEncryptBytes);
        toBeEncryptBytes = NULL;
    }

    return output;
}