簡體   English   中英

在PHP中復制C#加密/解密

[英]Replicate C# encryption/decryption in PHP

我從第三方獲得了一組需要加密/解密的代碼,但是他們給我的樣本加密代碼是在C#中,我主要是一名前端PHP開發人員。

我已經使用A818163DD5E0DE87的示例鍵設置我在這里提供的代碼的精簡工作示例。

public static byte[] HexStringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2) {
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}

// Convers a byte array to a HEX string
public static string ByteArrayToHexString(byte[] bytes)
{
StringBuilder hexString = new StringBuilder(bytes.Length * 2);
for (int i = 0; i < bytes.Length; i++)
{
hexString.Append(bytes[i].ToString("X2"));
}
return hexString.ToString();
}

public static byte[] Encrypt()
{
string plainText = "GROW06BP";
DESCryptoServiceProvider desCrypto = new DESCryptoServiceProvider();
desCrypto.Key = HexStringToByteArray("A818163DD5E0DE87");
desCrypto.IV = HexStringToByteArray("A818163DD5E0DE87");
desCrypto.Mode = CipherMode.CBC;
desCrypto.Padding = PaddingMode.Zeros;
// Create a buffer for the Plain Text using ASCIIEncoding
byte[] plaintextBytes = (new ASCIIEncoding()).GetBytes(plainText);
// Create a memory stream for the encrypted bytes
MemoryStream msEncrypt = new MemoryStream();
// Create a CryptoStream using the memory stream and the passed Algorithm
CryptoStream csEncrypt = new CryptoStream(msEncrypt, desCrypto.CreateEncryptor(), CryptoStreamMode.Write);
// Write the plaintext to the CryptoStream
csEncrypt.Write(plaintextBytes, 0, plaintextBytes.Length);
// Close the CryptoStream
csEncrypt.Close();
// Read the Encrypted bytes into our buffer
byte[] encryptedTextBytes = msEncrypt.ToArray();
// Close the Memory Stream
msEncrypt.Close();
// And return the encrypted buffer
return encryptedTextBytes;
}

我已經搜索了堆棧溢出和其他站點,試圖在PHP中復制它,但沒有任何東西接近正確的輸出。 我也很困惑我打算使用哪種密碼以及如何轉換密鑰和iv來匹配C#示例。 以下是我到目前為止所嘗試的內容。

$key = unpack('H*', "A818163DD5E0DE87");
$key = "A818163DD5E0DE87";
$iv = $key;
$plaintext = "GROW06BP";
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext,MCRYPT_MODE_CBC, $iv);
echo base64_encode($ciphertext);

任何幫助,將不勝感激。

你需要考慮的事情:

  • DESCryptoServiceProvider - > mcrypt_module_open('des'
  • desCrypto.Mode = CipherMode.CBC; - > mcrypt_module_open(...,...,'cbc',
  • key,iv和密碼輸出用HexStringToByteArray()“處理”, pack('H *)可以撤消

因此,考慮到導致的.net小提琴( 7860D97E56DA6A40 )的輸出

<?php
$msgHex = '7860D97E56DA6A40'; 
$keyHex = 'A818163DD5E0DE87';
$ivHex = 'A818163DD5E0DE87';  // really? invalidates the use-case of an iv :-/

// this reverts the effect of HexStringToByteArray() 
$msg = pack('H*', $msgHex);
$key = pack('H*', $keyHex);
$iv = pack('H*', $ivHex);

// add error handing !
$module = mcrypt_module_open('des', '', 'cbc', '');
mcrypt_generic_init($module, $key, $iv);
$plaintext = mdecrypt_generic($module, $msg);
mcrypt_generic_deinit($module);

echo $plaintext;

輸出: GROW06BP

正如我在評論中已經提到的那樣,你在PHP代碼中使用了錯誤的算法,因為它是Rijndael。 您應該使用的是MCRYPT_DES

$key = "A818163DD5E0DE87";
// Here you need pack instead of unpack
$packKey = pack("H*",$key);
// you should use the key as the initialization vector
// use something like mcrypt_create_iv to generate an IV
$iv = $packKey;
$plaintext = "GROW06BP";
// replaced MCRYPT_RIJNDAEL_128 with MCRYPT_DES
$ciphertext = mcrypt_encrypt(MCRYPT_DES, $packKey, $plaintext,MCRYPT_MODE_CBC, $iv);
echo base64_encode($ciphertext);

這將產生與C#代碼相同的輸出

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM