Некоторое время назад я реализовал веб-API C # для предоставления информации.
Эта информация зашифрована и используется другими веб-сайтами C # или Classic ASP.
Это то, как я делаю шифрование / дешифрование с использованием методов EncryptRijndael и DecryptRijndael.
using System;
using System.Text;
namespace Encryption_Test
{
using System.IO;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Windows.Forms;
class RijndaelManagedEncryption
{
//http://www.codeproject.com/Tips/704372/How-to-use-Rijndael-ManagedEncryption-with-Csharp
#region Rijndael Encryption
/// <summary>
/// Encrypt the given text and give the byte array back as a BASE64 string
/// </summary>
/// <param name="text" />The text to encrypt
/// <param name="salt" />The pasword salt
/// <returns>The encrypted text</returns>
public static string EncryptRijndael(string text, string salt, string inputKey)
{
if (string.IsNullOrEmpty(text))
throw new ArgumentNullException("text");
var aesAlg = NewRijndaelManaged(salt, inputKey);
var blockSize = aesAlg.BlockSize;
var strK = System.Text.Encoding.ASCII.GetString(aesAlg.Key);
string s = strK;
var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
var msEncrypt = new MemoryStream();
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(text);
}
return Convert.ToBase64String(msEncrypt.ToArray());
}
#endregion
#region Rijndael Dycryption
/// <summary>
/// Checks if a string is base64 encoded
/// </summary>
/// <param name="base64String" />The base64 encoded string
/// <returns>
public static bool IsBase64String(string base64String)
{
base64String = base64String.Trim();
return (base64String.Length%4 == 0) &&
Regex.IsMatch(base64String, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);
}
/// <summary>
/// Decrypts the given text
/// </summary>
/// <param name="cipherText" />The encrypted BASE64 text
/// <param name="salt" />
/// <param name="inputKey"></param>
/// The pasword salt
/// <returns>De gedecrypte text</returns>
public static string DecryptRijndael(string cipherText, string salt, string inputKey)
{
if (string.IsNullOrEmpty(cipherText))
throw new ArgumentNullException("cipherText");
if (!IsBase64String(cipherText))
throw new Exception("The cipherText input parameter is not base64 encoded");
string text;
var aesAlg = NewRijndaelManaged(salt, inputKey);
var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
var cipher = Convert.FromBase64String(cipherText);
using (var msDecrypt = new MemoryStream(cipher))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
text = srDecrypt.ReadToEnd();
}
}
}
return text;
}
#endregion
#region NewRijndaelManaged
/// <summary>
/// Create a new RijndaelManaged class and initialize it
/// </summary>
/// <param name="salt" />
/// <param name="inputKey"></param>
/// The pasword salt
/// <returns>
private static RijndaelManaged NewRijndaelManaged(string salt, string inputKey)
{
if (salt == null) throw new ArgumentNullException("salt");
var saltBytes = Encoding.ASCII.GetBytes(salt);
var key = new Rfc2898DeriveBytes(inputKey, saltBytes);
var aesAlg = new RijndaelManaged();
aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); //256 / 8 = 32
aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8); //128 / 8 = 16
//string k = System.Text.Encoding.Default.GetString(aesAlg.Key);
//string i = System.Text.Encoding.Default.GetString(aesAlg.IV);
//string l = k + i;
#region testPHP
///*
// So it would seem the week point in the chain for PHP is the Rfc2898DeriveBytes
// */
//aesAlg.Key = Encoding.UTF8.GetBytes(inputKey);
//aesAlg.IV = Encoding.UTF8.GetBytes(salt);
//k = System.Text.Encoding.Default.GetString(aesAlg.Key);
//i = System.Text.Encoding.Default.GetString(aesAlg.IV);
//l = k + i;
#endregion testPHP
return aesAlg;
}
#endregion
}
}
Вы можете увидеть закомментированные, когда ближе к концу, где я просто установил Key и IV из предоставленных параметров, просто преобразовав их в byte []. Это выглядит нормально для PHP, но я бы не стал опускать Rfc2898DeriveBytes.
Он работает просто отлично, и сайты-потребители могут расшифровать информацию.
Вот моя (чья-то еще проблема, но я хочу помочь), теперь PHP-сайт должен использовать мой Web API. Кажется, они не могут этого сделать. Они утверждают, что это связано с тем, как создается IV.
Теперь это заставляет меня задуматься, если
Теперь я очень мало знаю о PHP, но обычно могу следить за потоком кода.
Я был бы признателен, если бы кто-нибудь сначала сказал мне, ДОЛЖЕН ли Достигнуть цели с помощью PHP, и если да, может быть, некоторые советы о том, как это сделать.
Обратите внимание — это использует Rfc2898DeriveBytes, который, как я считаю, является сутью проблемы, и ОТЛИЧАЕТ этот вопрос от других подобных.
Co-operation is the key to success!
This_is_the_password_salt
This_is_the_input_key
pLgIEjhNGDMfI0IynoAdbey3NKbOJzgUzYAlU14OWOpuZy7/lr7HRtFhiRKfjbZz
Ну что ж — после нахождения песочницы, которая может принять hash_hmac, я, кажется, подозревал, что это вызвано вами, ребята, и вашими комментариями ……
С помощью этот сайт.
и следующий код в нем (я просто надеюсь, что он ведет себя так же в реальной ситуации)
<?php
class Foo {
public function decrypt_full($key, $iv, $encrypted)
{
$dev = $this->pbkdf2("sha1", $key, $iv, 1000, 48, true);
$derived_key = substr($dev, 0, 32); //Keylength: 32
$derived_iv = substr($dev, 32, 16); // IV-length: 16
return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $derived_key, base64_decode($encrypted), MCRYPT_MODE_CBC, $derived_iv);
}
private function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
{
$algorithm = strtolower($algorithm);
if(!in_array($algorithm, hash_algos(), true))
die('PBKDF2 ERROR: Invalid hash algorithm.');
if($count <= 0 || $key_length <= 0)
die('PBKDF2 ERROR: Invalid parameters.');
$hash_length = strlen(hash($algorithm, "", true));
$block_count = ceil($key_length / $hash_length);
$output = "";
for($i = 1; $i <= $block_count; $i++) {
// $i encoded as 4 bytes, big endian.
$last = $salt . pack("N", $i);
// first iteration
$last = $xorsum = hash_hmac($algorithm, $last, $password, true);
// perform the other $count - 1 iterations
for ($j = 1; $j < $count; $j++) {
$xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
}
$output .= $xorsum;
}
return substr($output, 0, $key_length);
}
}
//###########################################################################################
$encrypted = "pLgIEjhNGDMfI0IynoAdbey3NKbOJzgUzYAlU14OWOpuZy7/lr7HRtFhiRKfjbZz";
$iv = "This_is_the_password_salt";
$key = "This_is_the_input_key";
$foo = new foo;
echo "<br/>";
echo "Encrypted String: ".$encrypted."<br/>";
echo "Decrypted string: ".$foo->decrypt_full($key, $iv, $encrypted )."<br/>";
?>
Выход …
Key: .g���13f^sI>M��j$\�+�od�mY# �!
IV: �2]��&y�q� WJ��
Decrypted: Co-operation is the key to success!
Не могу дождаться, чтобы рассказать PHP ребята;)
Других решений пока нет …