用PHP解密C#加密
不久前,我实现了一个C#web API来提供信息。用PHP解密C#加密,c#,php,encryption,rijndaelmanaged,C#,Php,Encryption,Rijndaelmanaged,不久前,我实现了一个C#web API来提供信息。 此信息经过加密,并被其他C#或经典ASP网站使用。 这就是我使用EncryptRijndael和DecryptRijndael方法进行加密/解密的方式 using System; using System.Text; namespace Encryption_Test { using System.IO; using System.Security.Cryptography; using System.Text.Reg
此信息经过加密,并被其他C#或经典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
}
}
使用系统;
使用系统文本;
名称空间加密测试
{
使用System.IO;
使用System.Security.Cryptography;
使用System.Text.RegularExpressions;
使用System.Windows.Forms;
类RijndaelManagedEncryption
{
//http://www.codeproject.com/Tips/704372/How-to-use-Rijndael-ManagedEncryption-with-Csharp
#区域Rijndael加密
///
///对给定文本进行加密,并将字节数组作为BASE64字符串返回
///
///要加密的文本
///盐这个词
///加密文本
公共静态字符串EncryptRijndael(字符串文本、字符串盐、字符串输入密钥)
{
if(string.IsNullOrEmpty(text))
抛出新的ArgumentNullException(“文本”);
var aesAlg=新管理(salt,输入键);
var blockSize=aesAlg.blockSize;
var strK=System.Text.Encoding.ASCII.GetString(aesAlg.Key);
字符串s=strK;
var encryptor=aesAlg.CreateEncryptor(aesAlg.Key,aesAlg.IV);
var msEncrypt=newmemoryStream();
使用(var csEncrypt=newcryptostream(msEncrypt,encryptor,CryptoStreamMode.Write))
使用(var swEncrypt=newstreamwriter(csEncrypt))
{
书写(文本);
}
返回Convert.tobase64字符串(msEncrypt.ToArray());
}
#端区
#Rijndael区双重加密
///
///检查字符串是否为base64编码
///
///base64编码字符串
///
公共静态bool IsBase64String(string base64String)
{
base64String=base64String.Trim();
返回(base64String.长度%4==0)&&
Regex.IsMatch(base64String,@“^[a-zA-Z0-9\+/]*={0,3}$”,RegexOptions.None);
}
///
///解密给定的文本
///
///加密的BASE64文本
///
///
///盐这个词
///解密文本
公共静态字符串DecryptRijndael(字符串密文、字符串salt、字符串输入密钥)
{
if(string.IsNullOrEmpty(密文))
抛出新的ArgumentNullException(“密文”);
如果(!IsBase64String(密文))
抛出新异常(“密文输入参数不是base64编码”);
字符串文本;
var aesAlg=新管理(salt,输入键);
var decryptor=aesAlg.CreateDecryptor(aesAlg.Key,aesAlg.IV);
var cipher=Convert.FromBase64String(密文);
使用(var msDecrypt=新内存流(密码))
{
使用(var csDecrypt=new CryptoStream(msDecrypt,decryptor,CryptoStreamMode.Read))
{
使用(var srDecrypt=newstreamreader(csDecrypt))
{
text=srDecrypt.ReadToEnd();
}
}
}
返回文本;
}
#端区
#新日达地区管理
///
///创建一个新的RijndaelManaged类并初始化它
///
///
///
///盐这个词
///
私有静态RijndaelManaged NewRijndaelManaged(字符串salt,字符串inputKey)
{
如果(salt==null)抛出新的ArgumentNullException(“salt”);
var saltBytes=Encoding.ASCII.GetBytes(salt);
var键=新的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);
//stringi=System.Text.Encoding.Default.GetString(aesAlg.IV);
//字符串l=k+i;
#区域测试PHP
///*
//因此,PHP链中的一周点似乎是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;
#端域测试
回归方程;
}
#端区
}
}
在接近结尾时,您可以看到注释掉的,我只是通过将提供的参数转换为字节[]来设置Key和IV。这对于PHP来说似乎没问题,但我不想忽略Rfc2898DeriveBytes
它工作得很好,消费网站能够减少信息量
现在是我的(其他人的问题,但我想提供帮助),一个PHP站点现在需要使用我的Web API。他们似乎做不到这一点。他们认为这是由于IV的产生方式
现在我想知道
- 要加密的字符串:
合作是成功的关键代码>
- Salt:
这是密码
<?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!