AES Java编码,红宝石解码 [英] AES java encoding, ruby decoding

查看:115
本文介绍了AES Java编码,红宝石解码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Java中对AES进行数据编码,通过网络发送并在ruby中对其进行解码。

I'm trying to AES encode data in java, send it over the network and decode it in ruby.

基本字符串可以正常工作,但是一旦字符串长度是16个字节或更多,我在解码后的红宝石字符串的编码中有垃圾。我想这与填充有关(虽然不确定,因为它甚至会影响精确大小为16的字符串)

Works fine with basic strings, but once the string's length is 16 bytes or more, I have garbage at the encode of the decoded ruby string. I guess it has to do with padding (not sure though since it affects even strings with the exact size of 16)

我尝试使用PKCS或只是在空格处添加空格我的字符串的末尾匹配没有运气的确切长度

I tried using PKCS or just adding white space at the end of my string to match the exact length with no luck

任何人都可以解释为什么我必须在ruby中做一个 aes-256-cbc,知道我的java代码使用aes 128?在ruby中尝试aes-128-cbc不适用于任何字符串

Also can anyone explain why I have to do a "aes-256-cbc" in ruby knowing that my java code uses aes 128? trying aes-128-cbc in ruby does not work for any string

任何帮助都将不胜感激

我的基本代码

Java

byte[] raw = key.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(str.getBytes());
return new BASE64Encoder().encode(encrypted);

Ruby

def aes_decrypt(key, encrypted)
decipher =OpenSSL::Cipher::Cipher.new("aes-256-cbc")
decipher.decrypt
decipher.padding = 0
decipher.key = key
d = decipher.update(encrypted)
d << decipher.final
logger.debug "email  #{d.to_s}"
return d.to_s
end


推荐答案

padding chaining

AES加密16字节的块,不多也不少。当您想加密一条可能长度超过16个字节的消息时,则必须决定如何将数据拆分为块并随后重新组合。基本拆分算法称为 ECB :这是拆分为单独加密的块。已知ECB在实际数据方面的能力很弱,因为ECB会泄漏有关哪些明文块彼此相等的信息(它们将被相同地加密),并且这种冗余经常发生在正常数据中。

AES encrypts blocks of 16 bytes, no more and no less. When you want to encrypt a message which is potentially longer than 16 bytes, then you have to decide how data is split into blocks and reassembled afterwards. The basic splitting algorithm is called ECB: this is "just a split" into blocks encrypted individually. ECB is known to be weak with real-world data because it leaks information about which plaintext blocks are equal to each other (they will be encrypted identically) and such redundancy often happens in "normal" data.

因此需要以某种方式随机化数据块,以便隐藏数据冗余。 CBC 模式通过链接执行此操作:块的处理取决于前一个块的加密结果。即,将要加密的纯文本块与前一个块加密的输出组合在一起(按位XOR)。

Thus it is needed to "randomize" the data blocks in some way, so that data redundancy is hidden. The CBC mode performs that through "chaining": the processing of a block depends on the result of the encryption of the previous block. Namely, the to-encrypt plaintext block is combined (with bitwise XOR) with the output of the previous block encryption.

这里的重点是要加密的第一个块(数据的前16个字节)没有上一个块,因此无需进行XOR处理。这是通过选择随机IV,即16个随机字节的序列来解决的,该序列将用作XORing步骤的块-1。解密方必须知道IV(否则它将不知道对解密的块执行XOR运算,并且前16个字节的数据将无法理解)。好的一面是,静脉注射不需要保密。必须对其进行统一选择(不能为每个消息递增计数器),但是可以明文传输,通常沿着加密消息本身进行传输。

The important point here is that the first block to encrypt (the first 16 bytes of data) has no "previous block" so there is nothing to XOR with. This is solved by choosing a "random IV", i.e. a sequence of 16 random bytes, which will be used as "block -1" for the XORing step. The IV must be known to the decrypting party (otherwise it will not know what to XOR the decrypted block with, and the first 16 bytes of data will not be intelligible). The bright side is that the IV needs not be secret; it MUST be selected uniformly (it cannot be a counter incremented for each message), but it can be transmitted "in the clear", usually along the encrypted message itself.

因此,您不必担心IV,在Java或Ruby代码中我什么都看不到。通常,Java默认为ECB(因此完全没有IV)。如果Ruby在CBC中默认为全零IV(从概念上来说是不安全的),那么可以解密第一个块(将其写下来,它可以正常工作)是正常的,但同样正常

So you have to worry a bit about the IV, and I see nothing about it in either the Java or Ruby code. Usually, Java defaults to ECB (hence no IV at all). If Ruby defaults to an "all-zero IV" in CBC (which is, conceptually, insecure), then it is normal that you can decrypt the first block (write it down, it "just works"), but it is equally normal that it does not work for subsequent blocks.

因此,我建议您显式使用CBC(在Java中,使用 AES / CBC / PKCS5Padding 作为算法名称,而不是 AES )并管理IV(随后必须将其传输;您可以采用惯例将IV权限串联

So I suggest that you explicitly use CBC (in Java, use "AES/CBC/PKCS5Padding" as algorithm name, not "AES") and manage the IV (which must then be transmitted; you could take the convention to concatenate the IV right before the encrypted message).

其他一些说明:


  • 填充是关于将一​​些数据添加到明文中,以便您具有适当的输入长度。 CBC要求输入长度的长度应为块大小(16个字节)的倍数。 PKCS#5填充是一种流行的方法,通过该填充,您可以添加至少1个字节,最多16个字节,以使它们都具有值 n ,其中 n 是添加的字节数。然后,接收方可以(明确地)知道添加了多少个字节,并将其删除。 Java可以为您添加填充,而我想Ruby也可以在需要时自动处理填充。

  • Padding is about adding some data to the plaintext so that you have an appropriate input length. CBC requires that the input length has a length multiple of the block size (16 bytes). The PKCS#5 padding is a popular method, by which you add at least 1 byte, at most 16 bytes, such that all of them have value n where n is the number of added bytes. The receiver can then know (unambiguously) how many bytes were added, and remove them. Java can add the padding for you, and I suppose Ruby can also process the padding automatically if nicely asked.

在Java代码中,您使用 key.getBytes()。我想 key String 。知道 getBytes()是根据平台默认字符集对字符串进行编码的,该字符集在全球范围内并不总是相同的。通过指定显式字符集,您将省去一些麻烦。另外,由于您想使用128位密钥,但是在Ruby端只能通过 AES-256获得某些东西,因此我假设您实际上在Java端使用了256位密钥。我的猜测是您的 key 字符串是密钥的十六进制表示形式,为32个字符。 key.getBytes()不解释十六进制数字。它会对字符本身进行编码,产生一个32字节的数组-和32字节,即256位,而不是128位。

In the Java code, you use key.getBytes(). I suppose that key is a String. Know that getBytes() encodes the string according to the platform default character set, which is not always the same worldwide. You will save some worry by specifying an explicit charset. Also, since you want to use a 128-bit key but you get something on the Ruby side only with "AES-256", then I assume that you are actually using a 256-bit key on the Java side. My guess is that your key string is the hexadecimal representation of your key, as 32 characters. key.getBytes() does not interpret hexadecimal digits; it encodes the characters themselves, yielding a 32-byte array -- and 32 bytes, that's 256 bits, not 128.

这篇关于AES Java编码,红宝石解码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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