你如何使用DES加密在C地穴库? (setkey的,加密,地穴等) [英] How do you use the crypt library in C for DES encryption? (setkey, encrypt, crypt, etc.)

查看:134
本文介绍了你如何使用DES加密在C地穴库? (setkey的,加密,地穴等)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要做一些简单的DES加密用C与一些老code接口。据我了解,你可以使用地窖库这一点,与功能的setkey,加密,地穴,等我一直在搞乱它并不能得到它的权利。对于setkey的/加密手册页的例子是缺乏的。

我想,我将能够使用一些Java code来获得(见下文)。

相同的输出

所以我们可以说我有两个字符数组用C

 的char *消息=hellothe;
字符*键=iamakey0;

有人能给出如何将这些与setkey的/加密加密的例子,得到相同的结果,同时我也会在java code?我知道你必须把信息和密钥为64字节数组,其中每个字符重新presents了一点,但有些被混淆了。显然,你必须得到位奇偶校验正确的,太多的东西?

 公共静态的byte [] encryptDES(字节[]消息,字节[]键){
    字节[] =加密新的字节[0];
    尝试{
        密码C = Cipher.getInstance(DES);
        c.init(Cipher.ENCRYPT_MODE,新SecretKeySpec(关键,DES));
        加密= c.doFinal(消息);
    }
    赶上(例外五){
        e.printStackTrace();
    }
    返回加密;
}


解决方案

由于你调用 Cipher.getInstance 只用字符串DES ,你不指定密码方式或填充的方法。这意味着你得到了默认值,这取决于你所使用的Java加密提供者 - 你需要知道他们是写兼容C.(你真的应该指定他们,而不是依赖于缺省)到底是什么

如果您使用的SunJCE提供,则DES的默认值是ECB模式和PKCS#5填充。要做到这一点,最好的办法可能是使用OpenSSL或其他肉的密码库 - 但如果你想使用,通常是在UNIX类平台的标准C库中的函数,在 ecb_crypt 系列函数将是一个更容易与比 setkey的 / 加密家庭工作。

解密时,您将需要添加PKCS#加密时5填充,并检查(和丢弃))。以下 ecb_pkcs5_encrypt 函数应该做的使用这些功能上面的Java code大致相当于

  / *返回包含'数据'的内容,新分配的缓冲区,
 *填充到使用PKCS#5样式填充8字节的倍数。
 *
 *如果`padded_len`非NULL,它指向的值更新为
 *填充的输出数据的大小。
 *
 *出错返回NULL。
 * /
字符* pad_pkcs5(为const char *的数据,为size_t DATA_LEN,为size_t * padded_len)
{
    字符* padded_data;
    无符号padding_len = 8 - (DATA_LEN 8%);
    为const char填充= padding_len;
    字符* pad_ptr;    / *检查长度溢出* /
    如果(DATA_LEN + padding_len< D​​ATA_LEN)
        返回NULL;    / *数据复制到一个新的缓冲区和垫出来* /
    padded_data =的malloc(DATA_LEN + padding_len);    如果(!padded_data)
        返回NULL;    的memcpy(padded_data,数据,DATA_LEN);    如果(* padded_len)
    {
        * padded_len = DATA_LEN + padding_len;
    }    / *添加填充字节* /
    pad_ptr = padded_data + DATA_LEN;
    而(padding_len--)
    {
        * pad_ptr ++ =填充;
    }    返回padded_data;
}/ *返回包含'数据'的内容,新分配的缓冲区,
 *使用DES / ECB / PKCS5`键加密。
 *
 *如果`out_len`非NULL,价值指向更新为
 *加密的输出数据的大小(这往往会出现
 * 8的倍数)。
 *
 *出错返回NULL。
 * /
字符* ecb_pkcs5_encrypt(为const char *键,为const char *的数据,为size_t DATA_LEN,为size_t * out_len)
{
    炭des_key [8];
    字符* padded_data;
    为size_t padded_len;
    INT状态;    / *为数不多的情况下,函数strncpy()正是我们想要的! * /
    函数strncpy(des_key,钥匙,sizeof的des_key);
    des_setparity(des_key);    padded_data = pad_pkcs5(数据,DATA_LEN,&安培; padded_len);    如果(!padded_data)
        返回NULL;    状态= ecb_crypt(des_key,padded_data,padded_len,DES_ENCRYPT);    如果(DES_FAILED(状态))
        返回NULL;    如果(out_len)
        * out_len = padded_len;    返回padded_data;
}

I need to do some simple DES encryption in C to interface with some old code. From what I understand you can use the "crypt" library for this, with the functions setkey, encrypt, crypt, etc. I have been messing with it and can't get it right. The example on the man page for setkey/encrypt is lacking.

I want to get the same output as I would be able to get with some java code (see below).

So let's say I have two character arrays in C.

char *message = "hellothe";
char *key = "iamakey0";

Can someone give an example of how to encrypt these with setkey/encrypt and get the same result as I would from the java code? I realize you have to put message and key into a 64-byte array where each char represents a bit, but some of that is confusing too. Apparently you have to get the bit parity right on that too or something?

public static byte[] encryptDES(byte[] message, byte[] key) {
    byte[] encrypted = new byte[0];
    try{
        Cipher c = Cipher.getInstance("DES");
        c.init(Cipher.ENCRYPT_MODE,new SecretKeySpec(key,"DES"));
        encrypted = c.doFinal(message);
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    return encrypted;
}

解决方案

Because you're calling Cipher.getInstance with just the string "DES", you're not specifying a cipher mode or padding method. This means you get the defaults, which depends on what Java cryptography provider you're using - you need to know exactly what they are to write compatible C. (You really should be specifying them rather than relying on defaults).

If you're using the SunJCE provider, then the defaults for DES are ECB mode and PKCS #5 padding. The best way to do this is probably to use OpenSSL or another meaty crypto library - but if you want to use functions that are usually found in the standard C library on UNIX-type platforms, the ecb_crypt family of functions is going to be a lot easier to work with than the setkey / encrypt family.

You will need to add PKCS#5 padding when encrypting, and check it (and discard it) when decrypting). The following ecb_pkcs5_encrypt function should do the rough equivalent of the above Java code using those functions.

/* Returns a newly-allocated buffer containing the contents of `data',
 * padded out to a multiple of 8 bytes using PKCS #5 style padding.
 *
 * If `padded_len` is non-NULL, the value it points to is updated to
 * the size of the padded output data.
 *
 * Returns NULL on error.
 */
char *pad_pkcs5(const char *data, size_t data_len, size_t *padded_len)
{
    char *padded_data;
    unsigned padding_len = 8 - (data_len % 8);
    const char padding = padding_len;
    char *pad_ptr;

    /* check for length overflow */
    if (data_len + padding_len < data_len)
        return NULL;

    /* Copy data into a new buffer and pad it out */
    padded_data = malloc(data_len + padding_len);

    if (!padded_data)
        return NULL;

    memcpy(padded_data, data, data_len);

    if (*padded_len)
    {
        *padded_len = data_len + padding_len;
    }

    /* Add the padding bytes */
    pad_ptr = padded_data + data_len;
    while (padding_len--)
    {
        *pad_ptr++ = padding;
    }

    return padded_data;
}

/* Returns a newly-allocated buffer containing the contents of `data',
 * encrypted with `key' using DES/ECB/PKCS5.
 *
 * If `out_len` is non-NULL, the value it points to is updated to
 * the size of the encrypted output data (which will always be a
 * multiple of 8).
 *
 * Returns NULL on error.
 */
char *ecb_pkcs5_encrypt(const char *key, const char *data, size_t data_len, size_t *out_len)
{
    char des_key[8];
    char *padded_data;
    size_t padded_len;
    int status;

    /* One of the few cases where strncpy() is exactly what we want! */
    strncpy(des_key, key, sizeof des_key);
    des_setparity(des_key);

    padded_data = pad_pkcs5(data, data_len, &padded_len);

    if (!padded_data)
        return NULL;

    status = ecb_crypt(des_key, padded_data, padded_len, DES_ENCRYPT);

    if (DES_FAILED(status))
        return NULL;

    if (out_len)
        *out_len = padded_len;

    return padded_data;
}

这篇关于你如何使用DES加密在C地穴库? (setkey的,加密,地穴等)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆