IDEA加密

制卡人

成员
已加入
一月12,2019
留言内容
20
编程经验
Beginner
使用IDEA,我需要加密一个块(8个字节)。网络中的一些例子 //github.com/LexBritvin/IdeaCipher 用于整个文件,我只需要一个块。

到目前为止,我已经有了这段代码,但是加密结果是错误的:


C#:
byte[] data = new byte[8] { 0x50,0x5E,0xAF,0x43,0xA0,0xDF,0x32,0x29};
    string charKey = "3BD1955BEAA4428ADCC576F4DB752D00";

    bool encrypt = true;
    private static int blockSize = 8;

    private void button1_Click(object sender, EventArgs e)
    {
        Idea idea = new Idea(charKey, encrypt);
        BlockStreamCrypter bsc = new BlockStreamCrypter(idea, encrypt);
        bsc.crypt(data,0);
    }

    private class BlockStreamCrypter
    {
        Idea idea;
        bool encrypt;
        // data of the previous ciphertext block
        byte[] prev;
        byte[] newPrev;
        public BlockStreamCrypter(Idea idea, bool encrypt)
        {
            this.idea = idea;
            this.encrypt = encrypt;
            prev = new byte[blockSize];
            newPrev = new byte[blockSize];
        }
        public void crypt(byte[] data, int pos)
        {
            if (encrypt)
            {
                xor(data, pos, prev);
                idea.crypt(data, pos);
                Array.Copy(data, pos, prev, 0, blockSize);
            }

            else
            {
                Array.Copy(data, pos, newPrev, 0, blockSize);
                idea.crypt(data, pos);
                xor(data, pos, prev);
                byte[] temp = prev;
                prev = newPrev;
                newPrev = temp;
            }

            string fff = BitConverter.ToString(data);
            MessageBox.Show(fff);
        }
    }

    private static void xor(byte[] a, int pos, byte[] b)
    {
        for (int p = 0; p < blockSize; p++)
        {
            a[pos + p] ^= b[p];
        }
    }[/XCODE]

Also the namespace:
[XCODE]
namespace Idea_crypt
{
class Idea
{
    // Number of rounds.
    internal static int rounds = 8;
    // Internal encryption sub-keys.
    internal int[] subKey;

    public Idea(String charKey, bool encrypt)
    {
        byte[] key = generateUserKeyFromCharKey(charKey);
        // Expands a 16-byte user key to the internal encryption sub-keys.
        int[] tempSubKey = expandUserKey(key);
        if (encrypt)
        {
            subKey = tempSubKey;
        }
        else
        {
            subKey = invertSubKey(tempSubKey);
        }
    }

    /**
     * Encrypts or decrypts a block of 8 data bytes.
     *
     * @param data
     *    Buffer containing the 8 data bytes to be encrypted/decrypted.
     */
    public void crypt(byte[] data)
    {
    crypt(data, 0);
    }

    /**
     * Encrypts or decrypts a block of 8 data bytes.
     *
     * @param data
     *    Data buffer containing the bytes to be encrypted/decrypted.
     * @param dataPos
     *    Start position of the 8 bytes within the buffer.
     */
    public void crypt(byte[] data, int dataPos)
    {
        int x0 = ((data[dataPos + 0] & 0xFF) << 8) | (data[dataPos + 1] & 0xFF);
        int x1 = ((data[dataPos + 2] & 0xFF) << 8) | (data[dataPos + 3] & 0xFF);
        int x2 = ((data[dataPos + 4] & 0xFF) << 8) | (data[dataPos + 5] & 0xFF);
        int x3 = ((data[dataPos + 6] & 0xFF) << 8) | (data[dataPos + 7] & 0xFF);
        //
        int p = 0;
        for (int round = 0; round < rounds; round++)
        {
            int y0 = mul(x0, subKey[p++]);
            int y1 = add(x1, subKey[p++]);
            int y2 = add(x2, subKey[p++]);
            int y3 = mul(x3, subKey[p++]);
            //
            int t0 = mul(y0 ^ y2, subKey[p++]);
            int t1 = add(y1 ^ y3, t0);
            int t2 = mul(t1, subKey[p++]);
            int t3 = add(t0, t2);
            //

x0 = y0 ^ t2;
            x1 = y2 ^ t2;
            x2 = y1 ^ t3;
            x3 = y3 ^ t3;
        }
        //
        int r0 = mul(x0, subKey[p++]);
        int r1 = add(x2, subKey[p++]);
        int r2 = add(x1, subKey[p++]);
        int r3 = mul(x3, subKey[p++]);
        //
        data[dataPos + 0] = (byte)(r0 >> 8);
        data[dataPos + 1] = (byte)r0;
        data[dataPos + 2] = (byte)(r1 >> 8);
        data[dataPos + 3] = (byte)r1;
        data[dataPos + 4] = (byte)(r2 >> 8);
        data[dataPos + 5] = (byte)r2;
        data[dataPos + 6] = (byte)(r3 >> 8);
        data[dataPos + 7] = (byte)r3;
    }

    // Expands a 16-byte user key to the internal encryption sub-keys.
    private static int[] expandUserKey(byte[] userKey)
    {
        if (userKey.Length != 16)
        {
            throw new ArgumentException("Key length must be 128 bit", "key");
        }
        int[] key = new int[rounds * 6 + 4];
        for (int i = 0; i < userKey.Length / 2; i++)
        {

  key[i] = ((userKey[2 * i] & 0xFF) << 8) | (userKey[2 * i + 1] & 0xFF);
        }
        for (int i = userKey.Length / 2; i < key.Length; i++)
        {
            key[i] = ((key[(i + 1) % 8 != 0 ? i - 7 : i - 15] << 9) | (key[(i + 2) % 8 < 2 ? i - 14 : i - 6] >> 7)) & 0xFFFF;
        }
        return key;
    }

    // Inverts decryption/encrytion sub-keys to encrytion/decryption sub-keys.
    private static int[] invertSubKey(int[] key)
    {
        int[] invKey = new int[key.Length];
        int p = 0;
        int i = rounds * 6;
        invKey[i + 0] = mulInv(key[p++]);
        invKey[i + 1] = addInv(key[p++]);
        invKey[i + 2] = addInv(key[p++]);
        invKey[i + 3] = mulInv(key[p++]);
        for (int r = rounds - 1; r >= 0; r--)
        {
            i = r * 6;
            int m = r > 0 ? 2 : 1;
            int n = r > 0 ? 1 : 2;
            invKey[i + 4] = key[p++];
            invKey[i + 5] = key[p++];
            invKey[i + 0] = mulInv(key[p++]);
            invKey[i + m] = addInv(key[p++]);
            invKey[i + n] = addInv(key[p++]);
            invKey[i + 3] = mulInv(key[p++]);
        }
        return invKey;

   }

    // Addition in the additive group.
    // The arguments and the result are within the range 0 .. 0xFFFF.
    private static int add(int a, int b)
    {
        return (a + b) & 0xFFFF;
    }

    // Multiplication in the multiplicative group.
    // The arguments and the result are within the range 0 .. 0xFFFF.
    private static int mul(int a, int b)
    {
        long r = (long)a * b;
        if (r != 0)
        {
            return (int)(r % 0x10001) & 0xFFFF;
        }
        else
        {
            return (1 - a - b) & 0xFFFF;
        }
    }

    // Additive Inverse.
    // The argument and the result are within the range 0 .. 0xFFFF.
    private static int addInv(int x)
    {
        return (0x10000 - x) & 0xFFFF;
    }

    // Multiplicative inverse.
    // The argument and the result are within the range 0 .. 0xFFFF.
    // The following condition is met for all values of x: mul(x, mulInv(x)) == 1
    private static int mulInv(int x)
    {
        if (x <= 1)
        {
            return x;
        }
        int y = 0x10001;
        int t0 = 1;
        int t1 = 0;
        while (true)
        {
            t1 += y / x * t0;
            y %= x;
            if (y == 1)
            {
                return 0x10001 - t1;
            }
            t0 += x / y * t1;
            x %= y;
            if (x == 1)
            {
                return t0;
            }
        }
    }
    // Generates a 16-byte binary user key from a character string key.
    private static byte[] generateUserKeyFromCharKey(String charKey)
    {
        int nofChar = 0x7E - 0x21 + 1;    // Number of different valid characters
        int[] a = new int[8];
        for (int p = 0; p < charKey.Length; p++)
        {
            int c = charKey[p];

            for (int i = a.Length - 1; i >= 0; i--)
            {
                c += a[i] * nofChar;
                a[i] = c & 0xFFFF;
                c >>= 16;
            }
        }
        byte[] key = new byte[16];
        for (int i = 0; i < 8; i++)
        {
            key[i * 2] = (byte)(a[i] >> 8);
            key[i * 2 + 1] = (byte)a[i];
        }
        return key;
    }
}
}

加密以上数据时,结果必须为B93A652F011657A1
有人可以帮忙吗?
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,524
地点
悉尼,澳大利亚
编程经验
10+
加密在字节数组上执行。如果您有一个加密文件的示例,则它必须将该文件的部分或全部读取到字节数组中,然后再对其进行加密。如果您的文件仅包含这八个字节,那将是完全相同的事情。我无法代表其他人,但我不准备遵循您提供的链接来尝试查找示例,对其进行检查,弄清它们在做什么,然后将其与您已发布的相当大的代码块进行比较。为了让我仔细看一下,您需要将其范围缩小一点。
 
最佳 底部