Привет, у меня есть алгоритм шифрования в C#, и мне нужно его перенести в ruby.Преобразование алгоритма шифрования C# в Ruby
private string Encrypt(string clearText)
{
string EncryptionKey = "ENC_KEY";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x5, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream()) {
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length); cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray()); }
}
return clearText;
}
Как я понимаю alghorithm генерирует ключ AES, а также внутривенно и шифровать и возвращают в качестве базы 64 строки.
Я не нашел точной альтернативы для Rfc2898DeriveBytes, и я использовал PBKDF2 Gem. И вот мой рубиновый метод:
def self.encrypt clear_text
iterations = 1000
encryption_key = 'EncryptionKey'
clearBytes = clear_text.encode('UTF-16LE').bytes.to_a
enc_bytes = [0x1, 0x2, 0x3, 0x4, 0x5, 0x5, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11]
salt = enc_bytes.pack('C*')
derived_a = PBKDF2.new do |p|
p.password = encryption_key
p.salt = salt
p.iterations = iterations
p.key_length = 32
end
derived_b = PBKDF2.new do |p|
p.password = encryption_key
p.salt = salt
p.iterations = iterations
p.key_length = 16
end
key = derived_a.bin_string
# iV = derived_b.bin_string
iV_a = iV_a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] # Static iV
iV = iV_a.pack('C*')
cipher = OpenSSL::Cipher::AES256.new(:CBC)
cipher.encrypt
cipher.key = key
cipher.iv = iV
encrypted = cipher.update(clear_text) + cipher.final
Base64.encode64(encrypted)
end
У меня есть 2 проблемы в моем коде. я не могу получить такое же значение на iv, и если я использую его как статическое значение, возвращаемые значения не совпадают.
У меня слишком много опыта C#. Что мне не хватает?
MSDN говорит, что функция getBytes меняет размеры ключей для каждого вызова. Я имею в виду, если вы дважды вызываете GetBytes (10), это то же самое, что и вызов GetBytes (10 + 10) или непосредственно GetBytes (20). Существует несколько способов решения этой проблемы, и вы можете генерировать более длинный ключ при первом вызове, а затем разрезать его как на производный ключ, так и на IV. –
Если у вас мало опыта работы с C#, я бы предложил вам не «переводить» код, а просто написать его в Ruby с нуля. Если вы более знакомы с Ruby, это может быть проще, чем пытаться расшифровать неизвестный язык. – onebree