phpseclib подписывает и проверяет на С#

Мне нужно подписать строку закрытым ключом, используя RSA phpseclib, а затем проверить ее в С#. Я видел много примеров того, как шифровать в C# и расшифровывать в php, но ни один из примеров того, как подписать строку в php и проверить в .NET.

вот php-код:

include('Crypt/RSA.php');

$info = "Something";
$PrivateKey= "<RSAKeyValue><Modulus>3C5QWo4H+............"; //long string
$unsignedString = base64_encode($info);
$signedString = HashAndSignBytes($info, $PrivateKey);
file_put_contents('file.txt', $unsignedString."\n".$signedString);

function HashAndSignBytes($stringToSign, $Key) {
  $rsa = new Crypt_RSA();
  $rsa->loadKey($Key); // private key
  $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
  $signature = $rsa->sign($stringToSign);
  return base64_encode($signature);
}

и вот моя попытка прочитать файл и проверить его на С#:

const string publicKey = @"<RSAKeyValue><Modulus>3C5QWo4H.....";
TextReader reader = new StreamReader(path, Encoding.ASCII);
var unsignedString = reader.ReadLine();
var signedString = reader.ReadLine();
reader.Close();

if (VerifySignedHash(unsignedString,signedString, publicKey)) {
  //some code
}

private bool VerifySignedHash(string stringToVerify, string signedString, string publicKey)
    {
        var byteConverter = new ASCIIEncoding();
        var dataToVerify = Convert.FromBase64String(stringToVerify);
        var signedData = Convert.FromBase64String(signedString);
        try
        {
            // Create a new instance of RSACryptoServiceProvider using the 
            // key from RSAParameters.
            var rsaAlg = new RSACryptoServiceProvider();
            rsaAlg.FromXmlString(publicKey);

            // Verify the data using the signature.  Pass a new instance of SHA1CryptoServiceProvider
            // to specify the use of SHA1 for hashing.
            return rsaAlg.VerifyData(dataToVerify, new SHA1CryptoServiceProvider(), signedData);

        }
        catch (CryptographicException e)
        {
            Console.WriteLine(e.Message);
            return false;
        }
    } 

проверка не проходит...


person CyrexLt    schedule 19.03.2014    source источник
comment
Почему ваш открытый ключ в С# равен закрытому ключу в php? Или это просто оптическая иллюзия?   -  person Dmitry    schedule 20.03.2014
comment
Поскольку для подписи используется закрытый ключ, для проверки используется открытый ключ. В С# я использую открытый ключ   -  person CyrexLt    schedule 20.03.2014
comment
исправил код для ответа ниже   -  person CyrexLt    schedule 20.03.2014


Ответы (1)


В вашем «подписывающем» коде вы base64encode исходную строку, а затем записываете эту строку в выходной файл. Однако на стороне C# вы читаете это значение в unsignedString, но никогда не обращаете кодировку base64.

Конечным результатом является то, что вы пытаетесь проверить байты строки base64Encoded, а не сами данные, поэтому шаг VerifyData не выполняется.

Думай, это твоя проблема.

Изменение следующей строки может решить проблему:

var dataToVerify = Convert.FromBase64String(stringToVerify);
person David W    schedule 19.03.2014
comment
Да, это была проблема. Спасибо - person CyrexLt; 20.03.2014
comment
Большой! Рад быть полезным. - person David W; 20.03.2014