Różne szyfrogramy AES128 z php i c#

0

Witam,
chciałbym powiązać aplikację WinRT z serwerem w PHP. Mam implementacje AesCbcPkcs7 w c# i to samo chciałbym zrobić w PHP. Kod w c#

 public static string Encrypt(string Login)
		{
			var input = CryptographicBuffer.ConvertStringToBinary(Login, BinaryStringEncoding.Utf8);
			var BinKey = CryptographicBuffer.ConvertStringToBinary(Key, BinaryStringEncoding.Utf8);
			var BinIV = CryptographicBuffer.ConvertStringToBinary(IV, BinaryStringEncoding.Utf8);

			var Encryptor = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);

			var SymmKey = Encryptor.CreateSymmetricKey(BinKey);

			var encrypted = CryptographicEngine.Encrypt(SymmKey, input, BinIV);

			return CryptographicBuffer.EncodeToBase64String(encrypted);
		}

		public static string Decrypt(string LoginToDecode)
		{
			var input = CryptographicBuffer.DecodeFromBase64String(LoginToDecode);
			var BinKey = CryptographicBuffer.ConvertStringToBinary(Key, BinaryStringEncoding.Utf8);
			var BinIV = CryptographicBuffer.ConvertStringToBinary(IV, BinaryStringEncoding.Utf8);

			var Decryptor = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);

			var SymmKey = Decryptor.CreateSymmetricKey(BinKey);

			var Decrypted = CryptographicEngine.Decrypt(SymmKey, input, BinIV);

			return CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, Decrypted);
		}

Tu w PHP

function decryptRJ128($key,$iv,$string_to_decrypt)
{
    $string_to_decrypt = base64_decode($string_to_decrypt);
    $rtn = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $string_to_decrypt, MCRYPT_MODE_CBC, $iv);
    $rtn = rtrim($rtn, "\0\4");
    return($rtn);
}

function encryptRJ128($key,$iv,$string_to_encrypt)
{
    $rtn = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string_to_encrypt, MCRYPT_MODE_CBC, $iv);
    $rtn = base64_encode($rtn);
    return($rtn);
}    
 

Mając na wejściu:
Key = "lkirwf897+22#bbt"
•IV = "741952hheeyy66#c"
•password = "Asd"

Mam "eSy8m8ygN7rtC80DMdGOUQ==" z c# i
"GOO7yZL05XFce+cR4uIHRg==" w PHP.

Chciałbym, aby kod w c# i PHP były równoważne. Słabo znam się na PHP, więc jeśli o niego, proszę o dość łopatologiczne wyjaśnienia.

0

Najlepiej gdybyś użył tych samych bibliotek po obu stronach. Implementacje po obu stronach nie mogą się niczym różnić.

Przeczytaj to:
http://www.codeproject.com/Articles/223081/Encrypting-Communication-between-Csharp-and-PHP

0
vpiotr napisał(a):

Najlepiej gdybyś użył tych samych bibliotek po obu stronach. Implementacje po obu stronach nie mogą się niczym różnić.

Przeczytaj to:
http://www.codeproject.com/Articles/223081/Encrypting-Communication-between-Csharp-and-PHP

Czytałem już to, co znajduje się pod Twoim linkiem. Niestety, korzysta z bibliotek, które nie są dostępne w WinRT. Tutaj jest to samo, tyle, że w bardzo przystępny sposób:

http://stackoverflow.com/a/1765846

Niestety, nie mogę skorzystać z biblioteki System.Cryptography tylko Windows.Cryptography. Próbuje coś samemu skleić, ale wyniki są różne, niestety.

1

@Quiet uzywasz dwóch różnych algorytmów. Ten z PHP wygląda na podstawową implementacje AESa CBC podczas gdy ten z C# to implementacja z uwzględnieniem paddingu. Albo szukaj wspólnej implementacji (np. używaj openssl) albo użyj algorytmu który łatwiej zaimplementować jak np. RSA. Szyfrowanie oraz deszyfrowanie za pomocą RSA jest trywialne a jednocześnie równie bezpieczne. No i nie ma problemu o ile wysyłasz tylko krótkie dane.

0

W ogóle czytając ten temat dostaję trochę sprzecznych informacji.

Po pierwsze jeżeli korzystasz z hasła to klucz generuje się na jego podstawie więc nie wiem po co napisałeś coś o Password? Po Twoim kodzie wnioskuję, że jednak hasła nie potrzebujesz, bo nie używasz w ogóle klasy PasswordDeriveBytes, a klucz oraz IV podajesz z góry.

Po drugie parametrami AESmożesz dowolnie manipulować i możesz dopasować sobie parametry do takich jakie są w PHP. Pomijając oczywiście różnicę w implementacji. Nie wiem jak jest w PHP.

Napisałem taki oto programik w AES'a w C#. Może coś Ci to pomoże:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

public class Program {
    class Cipher {
        private AesCryptoServiceProvider _aes;
        public enum Process {
            Encryption,
            Decryption
        }

        public Cipher(byte[] key, byte[] iv) {
            this._aes = new AesCryptoServiceProvider();
            this._aes.KeySize = 128;
            this._aes.Mode = CipherMode.CBC;
            this._aes.Padding = PaddingMode.PKCS7;
            this._aes.Key = key;
            this._aes.IV = iv;
        }

        public byte[] Encrypt(byte[] plainText, Process process = Process.Encryption) {
            using (var stream = new MemoryStream()) {
                var direction = (process == Process.Encryption) ? this._aes.CreateEncryptor() : this._aes.CreateDecryptor();
                using (var crypto = new CryptoStream(stream, direction, CryptoStreamMode.Write)) {
                    crypto.Write(plainText, 0, plainText.Length);
                    crypto.Clear();
                    crypto.Close();
                }
                stream.Close();
                return stream.ToArray();
            }
        }

        public byte[] Decrypt(byte[] encryptedText) {
            return this.Encrypt(encryptedText, Process.Decryption);
        }

        public static string ToString(byte[] data) {
            return ASCIIEncoding.ASCII.GetString(data);
        }

        public static byte[] ToBytes(string data) {
            return ASCIIEncoding.ASCII.GetBytes(data);
        }
    }

    public static void Main() {
        var aes = new Cipher(Cipher.ToBytes("lkirwf897+22#bbt"), Cipher.ToBytes("741952hheeyy66#c"));
        var encrypted = aes.Encrypt(Cipher.ToBytes("Hello World!"));

        Console.WriteLine(Cipher.ToString(encrypted));
        Console.WriteLine(Cipher.ToString(aes.Decrypt(encrypted)));
    }
}
0

@Shalom masz racje. w PHP wystarczyło zastosować funkcje paddingu (pkcs7pad) i unpadingu. Obie funkcje zaczęły wypluwać te same szyfrogramy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1