【发布时间】:2014-10-03 01:51:41
【问题描述】:
我有一个使用 c# rsa 公钥加密密码的程序,它输出一个字节数组。
为了方便我传输它并维护数据,我将字节直接转换为十六进制字符串。现在这是我遇到问题的地方。我将发布数据发送到我的脚本,现在不确定将其转换为什么以及如何解密它。
我正在尝试使用 http://phpseclib.sourceforge.net/ 这篇帖子中提到的 RSA decryption using private key 文档非常模糊,我不知道解密()应该采用什么数据/类型。
<?php
include('Crypt/RSA.php');
if (isset($_POST['Password']))
{
$Password = $_POST['Password'];
$crypttext = pack("H*",$Password);
echo $cryptext;
$rsa = new Crypt_RSA();
$rsa->loadKey('key.priv');
$decryptedText =$rsa->decrypt($cryptext);
echo "Pass = >" . $decryptedText;
}
?>
请注意,这不会给出错误,但 $decryptedText 为空。
编辑:添加更多信息。
这是我的 c# 加密方法。
public static string Encrypt(string data, string keyLocation, string keyName)
{
Console.WriteLine("-------------------------BEGIN Encrypt--------------------");
// Variables
CspParameters cspParams = null;
RSACryptoServiceProvider rsaProvider = null;
string publicKeyText = "";
string result = "";
byte[] plainBytes = null;
byte[] encryptedBytes = null;
try
{
// Select target CSP
cspParams = new CspParameters();
cspParams.ProviderType = 1; // PROV_RSA_FULL
rsaProvider = new RSACryptoServiceProvider(2048, cspParams);
// Read public key from Server
WebClient client = new WebClient();
Stream stream = client.OpenRead(keyLocation + "/" + keyName);
StreamReader reader = new StreamReader(stream);
publicKeyText = reader.ReadToEnd();
//
//Console.WriteLine("Key Text : {0}",publicKeyText);
// Import public key
rsaProvider.FromXmlString(publicKeyText);
// Encrypt plain text
plainBytes = Convert.FromBase64String(data);
Console.WriteLine("inputlength : {0}",plainBytes.Length);
encryptedBytes = rsaProvider.Encrypt(plainBytes, false);
result = ByteArrayToString(encryptedBytes);
Console.WriteLine("Encrypted Hex string : {0}", result);
}
catch (Exception ex)
{
// Any errors? Show them
Console.WriteLine("Exception encrypting file! More info:");
Console.WriteLine(ex.Message);
}
rsaProvider.Dispose();
Console.WriteLine("-------------------------END Encrypt--------------------");
return result;
} // Encrypt
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length / 2;
byte[] bytes = new byte[NumberChars];
using (var sr = new StringReader(hex))
{
for (int i = 0; i < NumberChars; i++)
bytes[i] =
Convert.ToByte(new string(new char[2] { (char)sr.Read(), (char)sr.Read() }), 16);
}
return bytes;
}
public static string ByteArrayToString(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
我把php修改成了这个
<?php
include('Crypt/RSA.php');
if (isset($_POST['Password']))
{
$Password = $_POST['Password'];
$crypttext = pack("H*",$Password);
echo $cryptext;
$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents('key.priv')); // Added file_get_contents() which fixed the key loading
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1); // Added this which is essential thank you guys/gals
$decryptedText =$rsa->decrypt($cryptext);
echo "Pass = >" . $decryptedText; // gives unsual data. This needs to be converted from binary data to base64string I think
echo "Pass = >" . base64_encode($decryptedText); // gives no data.
echo "Pass = >" . base64_decode($decryptedText); // gives no data.
}
?>
我四处搜索并尝试了几件事来转换回文本,我尝试了 base64_encode() 和 base64_decode() 但我什么也没得到,否则我会得到 gobbledey gook。
【问题讨论】:
-
您的 C# 库使用什么加密算法/方案?我认为您必须在 php 中设置加密/解密模式,然后尝试。来自 phpseclib 站点
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1); -
我认为它是 RSA_Full,我从检查 php 库中收集到的一点是,这是 Crypt_RSA->decrypt() $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1); 的默认值。试过了
-
请向我们展示您的 C# 代码。这可能是由于错误的字符编码造成的。
-
嗯,是的,但我仍然不知道输入:
plainBytes = Convert.FromBase64String(data);。也许您也应该将 PHP 结果转换为 base 64。根据内容(控制字符等),它可能无法很好地打印。 -
如果
data是任意字符串,那么这种方法非常非常糟糕。是的,FromBase64String将字符串转换为字节数组 - 但它假定输入是有效的 base64!如果您尝试将 arbitrary 字符串转换为字节数组,则应使用编码,例如Encoding.UTF8.GetBytes(data)。 (然后,您需要对解密后获得的二进制数据进行解码,以获得字符串结果。)
标签: php cryptography rsa data-conversion phpseclib