2016-07-31 3 views
1

C#으로 작성된 암호화 코드를 PHP로 이식하려고합니다. 아래 코드는 Rijndael-128 암호화를 사용합니다. PHP 코드에 의해 주어진 결과는 C# 코드와 약간 다릅니다. 나는 Salt과 무작위 IV을 사용하지 않고, C# 코드를 변경하지 않는 제약 조건하에있다. 이 문제에 대한 stackoverflow에 대한 많은 답변을 살펴본 후 코드를 여러 번 변경해도 코드가 올바른 결과를 산출하지 못합니다.Rijndael C#에서 다른 결과를주는 PHP 변환

C# 코드 (클래스의 멤버 함수)

public static string Encrypt(string plainText, string passPhrase) 
{ 
    byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector); 
    byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); 
    var password = new Rfc2898DeriveBytes(passPhrase, new byte[8], 10000); 
    byte [] keyBytes= password.GetBytes(keysize/8); //256/8 
    var symmetricKey = new RijndaelManaged(); 
    symmetricKey.Mode = CipherMode.CBC; 
    ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes); 
    var memoryStream = new MemoryStream(); 
    var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write); 
    cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); 
    cryptoStream.FlushFinalBlock(); 
    byte[] cipherTextBytes = memoryStream.ToArray(); 
    memoryStream.Close(); 
    cryptoStream.Close(); 

    return Convert.ToBase64String(cipherTextBytes); 
} 

PHP 코드 (클래스의 멤버 함수)

public function encrypt(){ 

    $plainText="Same_input_as_above"; 

    $plainText=mb_convert_encoding($plainText,'UTF-8'); 

    $passPhrase=mb_convert_encoding($this->secret,'UTF-8'); 

    $salt=str_pad("",8,"\0"); 

    $key= hash_pbkdf2 ('sha1' , $passPhrase, $salt , 10000 ,self::KEYSIZE/8, true); 

    $initVector=mb_convert_encoding(self::INITVECTOR,'UTF-8'); 

    $tempCipher= mcrypt_encrypt (MCRYPT_RIJNDAEL_128 , $key , $plainText , MCRYPT_MODE_CBC,$initVector); 

    return base64_encode($tempCipher); 
} 

C# 1 출력

O/Fi4tfdS5APen6YAboRnr%2B2bSrHSG71OHhX7YZbbhJYr8mt3HxfYza4bjkV8gtq 

PHP 출력

O/Fi4tfdS5APen6YAboRnr%2B2bSrHSG71OHhX7YZbbhIpdOLx9oscZnlAdyTMgeGX 

C#의 암호 해독 기능은 자체적으로 생성 된 암호와 함께 작동하지만 PHP 생성 암호를 해독하는 동안 Padding is invalid and cannot be removed. 오류가 발생합니다.

+0

mcrypt는 사용하지 않는 것이 가장 좋으며 포기웨어이며 수년 내에 업데이트되지 않았으며 표준 PKCS # 7 (nee PKCS # 5) 패딩을 지원하지 않으며 심지어 사용할 수없는 비표준 널 패딩 만 지원합니다 이진 데이터. mcrypt는 2003 년으로 거슬러 올라가는 많은 [버그] (https://sourceforge.net/p/mcrypt/bugs/)를 가지고 있습니다. 대신 [defuse] (https://github.com/defuse/php-encryption) 또는 [RNCryptor] (https://github.com/RNCryptor), 그들은 완벽한 솔루션을 제공하고 있으며 유지 관리되고 있으며 정확합니다. – zaph

+0

@ArtjomB. 감사. 처음에는 null padded salt를 적용한 후에 문제가되는 빈 소금이라고 생각했습니다. 이후 일반 텍스트 패딩 라인의 주석 처리를 잊어 버렸습니다. – UDB

답변

1

mcrypt은 비표준 널 패딩 만 지원합니다. C# 라이브러리는 표준 PKCS # 7 (nee PKCS # 5) 패딩을 지원합니다. PKCS#7 padding을 참조하십시오.

할 수 있습니다 쉽게 PHP에 추가하고 이전에 암호화 및 암호 해독 후 PKCS 번호 7 패딩을 제거 :

추가 PKCS # 7 패딩

$padLength = $blockSize - (strlen($clearText) % $blockSize); 
$clearText = $clearText . str_repeat(chr($padLength), $padLength); 

스트립 PKCS # 7 패딩

$padLength = ord($cryptText[strlen($cryptText)-1]); 
$cryptText = substr($cryptText, 0, strlen($cryptText) - $padLength); 

더 좋은 해결책은 mcrypt을 사용하지 않는 것입니다. 옵션으로는 전체 솔루션을 제공하는 defuse 또는 RNCryptor이 있습니다.

+0

더 나은 솔루션을 제안 해 주셔서 감사하지만 패딩 제거를 해독 할 필요가 없었습니다. – UDB

관련 문제