2

Hello I am having trouble encrypting using an array as the key and the value with the ruby-mcrypt gem. The gem lets me use an array for the key fine, cipher = Mcrypt.new("rijndael-256", :ecb, secret) works. But it will give me an error when I try to encrypt. I've tried many things but no luck. Does anyone know if Mcrypt just doesn't like encrypting with an array?

require 'mcrypt'

def encrypt(plain, secret)
  cipher = Mcrypt.new("rijndael-256", :ecb, secret)
  cipher.padding = :zeros

  encrypted = cipher.encrypt(plain)
  p encrypted
  encrypted.unpack("H*").first.to_s.upcase
end

array_to_encrypt = [16, 0, 0, 0, 50, 48, 49, 55, 47, 48, 50, 47, 48, 55, 32, 50, 50, 58, 52, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
key_array = [65, 66, 67, 68, 49, 50, 51, 52, 70, 71, 72, 73, 53, 54, 55, 56]

result = encrypt(array_to_encrypt, key_array)
p "RESULT IS #{result}"

The output is as follows:

Mcrypt::RuntimeError: Could not initialize mcrypt: Key length is not legal.

I traced this error to here in the ruby-mcrypt gem but don't understand it enough to figure out why I am getting the error message. Any help or insights would be amazing. Thanks!

Gabriel
  • 621
  • 7
  • 19
  • Try `key_array.map(&:to_s)`? `key_array.map(&:size).inject(:+) => 128` whereas `key_array.map(&:to_s).map(&:size).inject(:+) => 32`. If Mcrypt is not changing the ints to strings it may be giving it a 128byte / 1024bit key instead of 32byte / 256bit – Tom Jan 02 '19 at 18:39
  • Thanks for the suggestion. Unfortunately I am still getting the same error. I was hoping that would work cause that makes sense. – Gabriel Jan 02 '19 at 18:45
  • Try doubling the length of the array [65, 66, 67, 68, 49, 50, 51, 52, 70, 71, 72, 73, 53, 54, 55, 56, 65, 66, 67, 68, 49, 50, 51, 52, 70, 71, 72, 73, 53, 54, 55, 56]`. That would match up with [this suggestion](https://stackoverflow.com/questions/36826445/rijndael-key-size-in-c-sharp) where their hex array is twice as long for a 256 rijndael. – Tom Jan 02 '19 at 19:41
  • Judging by the fact that [the `key` accessor returns a `String`](https://rubydoc.info/gems/ruby-mcrypt/Mcrypt:key) and reading [between the lines of the documentation for `key=`](https://rubydoc.info/gems/ruby-mcrypt/Mcrypt:key=), I would guess that the key needs to be a `String` in `Encoding::BINARY` encoding. – Jörg W Mittag Jan 02 '19 at 19:46
  • @Tom I did try that and still got the same error – Gabriel Jan 02 '19 at 19:53
  • @JörgWMittag I suspect you are correct about that. That was what I was thinking. Just wanted to see if anyone else could verify this is the case. – Gabriel Jan 02 '19 at 19:54

1 Answers1

1

The library doesn't support arrays. You'll need to use Strings instead:

def binary(byte_array)
  byte_array.pack('C*')
end

array_to_encrypt = [16, 0, 0, 0, 50, 48, 49, 55, 47, 48, 50, 47, 48, 55, 32, 50, 50, 58, 52, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
key_array = [65, 66, 67, 68, 49, 50, 51, 52, 70, 71, 72, 73, 53, 54, 55, 56]

result = encrypt(binary(array_to_encrypt), binary(key_array))
p "RESULT IS #{result}"
KingPong
  • 1,439
  • 1
  • 16
  • 22