Question

Je suis de la génération de données à envoyer à partir d'un Rubis de la pile une pile PHP.Je suis à l'aide d'OpenSSL::Chiffrement de la bibliothèque sur le Ruby côté et le "mcrypt" bibliothèque en PHP.Quand j'ai chiffrer à l'aide de 'aes-256-cbc" (256 bits, la taille de bloc) en Ruby, j'ai besoin d'utiliser MCRYPT_RIJNDAEL_128 (128 bits taille du bloc) en PHP pour le décrypter.Je soupçonne le code Ruby qui est cassé, parce que l'algorithme de chiffrement.iv_len est de 16 ans;Je crois qu'il devrait être 32:

>> cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
=> #<OpenSSL::Cipher::Cipher:0x3067c5c>
>> cipher.key_len
=> 16
>> cipher.iv_len
=> 16
>> cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
=> #<OpenSSL::Cipher::Cipher:0x306de18>
>> cipher.key_len
=> 32
>> cipher.iv_len
=> 16

Voici donc mon test.Sur le Ruby côté, j'ai d'abord générer la clé et iv:

>> cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
>> cipher.encrypt
>> iv = cipher.random_iv
>> iv64 = [iv].pack("m").strip
=> "vCkaypm5tPmtP3TF7aWrug=="
>> key = cipher.random_key
>> key64 = [key].pack("m").strip
=> "RIvFgoi9xZaHS/0Bp0J9WDRyND6Z7jrd3btiAfcQ8Y0="

Puis-je utiliser ces touches pour effectuer le chiffrement:

>> plain_data = "Hi, Don, this is a string."
>> cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
>> cipher.encrypt
>> cipher.key = Base64.decode64(key64)
>> cipher.iv = Base64.decode64(iv64)
>> encrypted_data = cipher.update(plain_data)
>> encrypted_data << cipher.final
>> crypt64 = [encrypted_data].pack("m").strip
=> "5gfC/kJcnAV2fJI0haxnLcdraIKWgtu54UoznVxf8K0="

Voici le PHP déchiffrement:

$ruby_crypt = "5gfC/kJcnAV2fJI0haxnLcdraIKWgtu54UoznVxf8K0=";
$encrypted_data = base64_decode($ruby_crypt);
$key = base64_decode("RIvFgoi9xZaHS/0Bp0J9WDRyND6Z7jrd3btiAfcQ8Y0=");
$iv = base64_decode("vCkaypm5tPmtP3TF7aWrug==");
$result = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted_data, MCRYPT_MODE_CBC, $iv);
$unencrypt = rtrim($result, "\x00..\x1F");
print "\nUnencrypted token:\n'$unencrypt'\n";

RESULT:
Unencrypted token:
'Hi, Don, this is a string.'

Je préfère utiliser le plus de la taille du bloc.Clairement, je suis l'incompréhension de l'Api.De l'aide?

Était-ce utile?

La solution

Je ne sais pas PHP, mais la lecture à travers des questions connexes sur la barre latérale, je vois Conversion Ruby AES256 fonction Décrypter vers PHP . Cela inclut une référence à cette page , indiquant que le 128 MCRYPT_RIJNDAEL_128 fait référence à la taille de bloc du chiffrement, pas la taille de la clé. Vous remarquerez que la taille de la clé que vous avez passé entre Ruby et PHP est de 256 bits dans les deux cas. En d'autres termes, cela semble être le comportement attendu, et que vous utilisez déjà la grande clé.

#!/usr/bin/ruby
require 'base64'

puts((Base64.decode64("RIvFgoi9xZaHS/0Bp0J9WDRyND6Z7jrd3btiAfcQ8Y0=").length * 8).to_s)

HTH

Autres conseils

J'ai écrit un exemple que quelqu'un d'autre peut trouver explicatif de la discussion ci-dessus:

$ cat éditeur.rb

#!/usr/bin/env ruby

require 'openssl'
require 'base64'

key = '7fc4d85e2e4193b842bb0541de51a497'

cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
cipher.encrypt()
iv = cipher.random_iv

cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
cipher.encrypt()
cipher.key = key
cipher.iv = iv
crypt = cipher.update('This is my text')
crypt << cipher.final()

puts [Base64.encode64(crypt).strip(), Base64.encode64(iv).strip()].join('|')

$ cat consumer.php

$key256 = '7fc4d85e2e4193b842bb0541de51a497';

$fd = fopen("php://stdin", "r");
$tokens = '';
while (!feof($fd))
  $tokens .= fread($fd, 1024);
fclose($fd);

$tokens = explode('|', trim($tokens));
$crypt = $tokens[0];
$iv = $tokens[1];

$crypttext = base64_decode($crypt);
$iv = base64_decode($iv);
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key256, $crypttext, MCRYPT_MODE_CBC, $iv);

print $decrypted ."\n";

Pour le tester, à partir de la ligne de commande, essayez:

$ ruby éditeur.rb | php consumer.php

C'est mon texte

J'ai eu des problèmes parce que le PHP utilisait un mot de passe plus petit que 8 caractères. Dans ce cas, il faut ajouter le 0, pour le rendre compatible avec PHP:

mcrypt-Crypter page de manuel « Touche

La clé avec laquelle les données seront cryptées. Si elle est plus petite que la taille de clé nécessaire, il est rembourré avec « \ 0 ». Il est préférable de ne pas utiliser des chaînes ASCII pour les touches. http://php.net/manual/en/function.mcrypt-encrypt.php Il est recommandé d'utiliser les fonctions de mhash pour créer une clé d'une chaîne. "

require 'openssl'
cipher = OpenSSL::Cipher.new('DES-ECB')
cipher.encrypt
key =  'passwrd'[0...7].ljust(8, 0.chr)  #Pad the key smaller than 8 chars
cipher.key = key
encrypted = cipher.update('33')
encrypted << cipher.final
dec = Base64.encode64(encrypted).strip()

Permettez-moi de vous montrer un peu de code.

Code PHP:

$privateKey = "1234567890123456"; # the size is 16.
$data = "hello";
$iv = "0123456789012345";

$result = mcrypt_encrypt(
  MCRYPT_RIJNDAEL_128, $privateKey, $data, MCRYPT_MODE_CBC, $iv
)

$base64str = base64_encode($result);
$base64str = str_replace("+", "-",  $base64str);
$base64str = str_replace("/","_",  $base64str);

# => f-WffBXnf122NcVBUZ6Rlg==

Code Ruby:

require 'base64'
require 'openssl'

private_key = "1234567890123456"
data = "hello"
iv = "0123456789012345"

cipher = OpenSSL::Cipher::AES.new(128, :CBC) 
cipher.encrypt

cipher.padding = 0 # we must disable padding in ruby.
cipher.key = private_key
cipher.iv = iv
block_size = cipher.block_size

# Add padding by yourself.
data = data + "\0" * (block_size - data.bytesize % block_size)
result = cipher.update(data) + cipher.final

Base64.urlsafe_encode64(result)
# ==> f-WffBXnf122NcVBUZ6Rlg==

Comme vous pouvez le voir, je suis en utilisant AES-128 en Ruby, car 16 est la taille de private_key. Donc, vous devez utiliser AES-256 si la taille de votre private_key est 32.

Formule:. size_of_private_key * 8

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top