对于Java

时间:2016-03-28 23:29:17

标签: java encryption aes

我正在尝试用Java实现AES(仅限学术用途)。

我采用默认实现来将我的结果与原始结果进行比较。

private byte[] crypt(int mode, byte[] key, byte[] initializationVector, byte[] data)
{
    try
    {
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, AES);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(initializationVector);

        cipher.init(mode, secretKeySpec, ivParameterSpec);

        return cipher.doFinal(data);
    }
    catch(BadPaddingException | InvalidKeyException | IllegalBlockSizeException | InvalidAlgorithmParameterException e)
    {
        throw new RuntimeException(e);
    }
}

其中int模式为Cipher.ENCRYPT_MODE或Cipher.DECRYPT_MODE。 注意,key,iv和data都是byte [](而不是char [])。

现在,当我尝试执行我的实现时,我遇到了Sboxes的问题。 我从维基百科中获取数组

https://en.wikipedia.org/wiki/Rijndael_S-box

例如,有unsigned char(例如C ++而不是Java)。

问题是:Java中的字节是否已签名(-128到127),因此当我想稍后将其用作数组索引时,其中一半是负数,导致问题的原因。

如果我将此sbox转换为byte [],那么我对数组的索引有疑问。 如果我决定在char []上做所有事情,那么我会将内存使用量加倍,而且我很难将我的结果与库存实现(使用byte [])进行比较。

我确信,实现股票加密的人比我聪明,所以我假设byte []是正确答案,但在这种情况下如何处理负数组索引?

当我需要非负表示时,我看到的唯一的是“偷偷摸摸”在byte和char之间进行转换,方法如下:

public class Sbox
{
    // it's array from wiki, 256 elements
    private final char substitute[] =
    {
        0x63, 0x7C, ... 0xBB, 0x16
    };

    public byte substitute(byte index)
    {
        return convert(substitute[convert(index)]);
    }

    private char convert(byte b)
    {
        return (char) (b < 0 ? b + 256 : b);
    }

    private byte convert(char c)
    {
        return (byte) (c < 256 ? c : 256 - c);
    }
}

当需要索引和返回时 - 这不是最有效的想法,看起来像我的bug。

如何做得更好? 应该是byte []还是char []作为默认结构? (用于密钥/ iv /数据) 顺便说一句,只是为了确定,cipher.doFinal(数据); (在库存实施中)是进行全加密,而不仅仅是最终(非标准)轮次? 股票实施是否使用AES-NI?

如果重要:我在美国境外,我已经解锁了无限制的加密版本。

0 个答案:

没有答案