2017-10-07 33 views
1

아래는 사용되는 공개 키는 다음과 같습니다 phpseclibrsacryptoserviceprovider.VerifyData는 항상 false를 돌려

static void Main(string[] args) 
     { 

      var payment = 
       "VUQxMzE1MTg0OTk0MDM2MzIyMDJ8VDAwMDAxN0kxMFVEMTMxNTE4NDk5NDAzNjMyMjAyfDIwMTctMTAtMDd8MHxwYXltZW50IHN1Y2Nlc3NmdWx8MjAyNTQ="; 
      var signature = 
       "V0T9ZedZW8oB9uy4PazRIxWHvJ7rR+FVtnGjUy30mSKqgmEceZWE1aBvkQWeG4ERjAXHjsRge0D0MlHd9zvXjrLog+G5nWBHIu52O0srCd9d71JVztMQy8fV5oSnRPtlUpgdmn8QDnJ27XrbaHzNxnFyybTQhmbfxkT0oJ0MEOk="; 

      var sigByte = Convert.FromBase64String(signature); 
      var payBite = Convert.FromBase64String(payment); 

      Verify(payBite, sigByte); 
     } 

     public static bool Verify(byte[] payment, byte[] signature) 
     { 
      var key = Resources.PublicKey; 
      var cipher = Crypto.DecodeX509PublicKey(key); 

      var res = cipher.VerifyData(payment, "SHA256", signature); 
      return res; 
     } 

를 사용하는 PHP 스크립트의 응답을 확인 내 C# 프로그램 :

-----BEGIN PUBLIC KEY----- 
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDSiXzUuH9ePZgSLYrzZ0qhta25 
HCb+WG48wIKUl+cQNC/Fl/KZG2cSwRXdo8KZLVWWO5qwzplfTWEylg4IqRA48rYY 
f/b+Y7QhORKeAws4pttLZJBbh1mIbZ9HXfQ+zBjP+zfJZ1YjSFs2uZdwSt1itUcJ 
/GQFct8GoUevNELG7wIDAQAB 
-----END PUBLIC KEY----- 

하지만 확인을 방법은 항상 false로 돌아 오는 것 같습니다. 왜 이런 일이 벌어 지는지.

공급 업체 내가 잘못 여기서 뭘하는지 나

<?php 
//load RSA library 
include 'Crypt/RSA.php'; 
//initialize RSA 
$rsa = new Crypt_RSA(); 
//decode & get POST parameters 
$payment = base64_decode("VUQxMzE1MTg0OTk0MDM2MzIyMDJ8VDAwMDAxN0kxMFVEMTMxNTE4NDk5NDAzNjMyMjAyfDIwMTctMTAtMDd8MHxwYXltZW50IHN1Y2Nlc3NmdWx8MjAyNTQ="); 
$signature = base64_decode("V0T9ZedZW8oB9uy4PazRIxWHvJ7rR+FVtnGjUy30mSKqgmEceZWE1aBvkQWeG4ERjAXHjsRge0D0MlHd9zvXjrLog+G5nWBHIu52O0srCd9d71JVztMQy8fV5oSnRPtlUpgdmn8QDnJ27XrbaHzNxnFyybTQhmbfxkT0oJ0MEOk="); 

//load public key for signature matching 
$publickey = "-----BEGIN PUBLIC KEY----- 
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDSiXzUuH9ePZgSLYrzZ0qhta25 
HCb+WG48wIKUl+cQNC/Fl/KZG2cSwRXdo8KZLVWWO5qwzplfTWEylg4IqRA48rYY 
f/b+Y7QhORKeAws4pttLZJBbh1mIbZ9HXfQ+zBjP+zfJZ1YjSFs2uZdwSt1itUcJ 
/GQFct8GoUevNELG7wIDAQAB 
-----END PUBLIC KEY-----"; 
$rsa->loadKey($publickey); 
//verify signature 
$signature_status = $rsa->verify($payment, $signature); 
//get payment response in segments 
//payment format: order_id|order_refference_number|date_time_transaction|payment_gateway_used|status_code|comment; 
$responseVariables = explode('|', $payment);  


    //display values 
    echo $signature_status; 

    echo '<br/>'; 
    var_dump($responseVariables); 


?> 

에 어떤 생각을 준 PHP 코드에서 동일한 콘텐츠 작품. 나는 "SHA512", "MD5"를 모두 C# 코드로 전달하려고했지만 여전히 false를 반환합니다.

+1

phpseclib 설명서에 따르면 기본 해시 알고리즘은 sha1입니다. C#에서 그 중 하나를 시도해 봤나? – Michael

+0

@Michael yeap. 그것도 역시 같은 결과를 주었다. – Aneef

+0

당신이 (PHP에서)'$ rsa-> setEncryptionMode (CRYPT_RSA_ENCRYPTION_PKCS1);'할 필요가 있는지 궁금하다. OAEP 암호화는 phpseclib가 기본적으로 사용하는 암호화입니다. PKCS1보다 안전하지만 덜 일반적으로 사용됩니다. – neubert

답변

2

음, 공급 업체가 PKCS1을 사용하지 않는 것처럼 보입니다. 그는 PSS를 사용하고 있습니다. 이런 식으로 확인 (탄력 성이 필요합니다!) :

public static bool Verify(byte[] payment, byte[] signature) 
    { 
     var pub = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDSiXzUuH9ePZgSLYrzZ0qhta25HCb+WG48wIKUl+cQNC/Fl/KZG2cSwRXdo8KZLVWWO5qwzplfTWEylg4IqRA48rYYf/b+Y7QhORKeAws4pttLZJBbh1mIbZ9HXfQ+zBjP+zfJZ1YjSFs2uZdwSt1itUcJ/GQFct8GoUevNELG7wIDAQAB"; 

     byte[] raw = Convert.FromBase64String(pub); 
     AsymmetricKeyParameter aKey = PublicKeyFactory.CreateKey(raw); 
     RsaKeyParameters rKey = (RsaKeyParameters)aKey; 

     PssSigner pss = new PssSigner(new RsaEngine(), new Sha1Digest(), 20); 
     pss.Init(false, rKey); 
     pss.BlockUpdate(payment, 0, payment.Length); 
     var res = pss.VerifySignature(signature); 

     return res; 
    } 
+0

예 .. 제 생각에는 그들의 의사와 구현이 다른 것 같습니다. 아이디어에 대해 감사드립니다. – Aneef

2

PSS 인 - 더 - 박스 .NET 4.6+와 지원되지만 RSACryptoServiceProvider을 기반으로 RSACng 클래스 (CAPI를 사용하여 필요하지 않습니다 그것을 제공하십시오).

public static bool Verify(byte[] payment, byte[] signature) 
{ 
    var key = Resources.PublicKey; 
    // Change the function this calls to return RSACng instead of RSACryptoServiceProvider. 
    RSA cipher = Crypto.DecodeX509PublicKey(key); 

    // or, failing being able to change it: 
    RSA tmp = new RSACng(); 
    tmp.ImportParameters(cipher.ExportParameters(false)); 
    cipher = tmp; 

    return cipher.VerifyData(
     payment, 
     signature, 
     HashAlgorithmName.SHA256, 
     RSASignaturePadding.Pss); 
}