2017-10-07 9 views
1

Ci-dessous mon programme C# qui vérifie une réponse d'un script php qui utilise phpseclibrsacryptoserviceprovider.VerifyData retourne toujours faux

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; 
     } 

la clé publique utilisée est la suivante:

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

mais le vérifier La méthode semble rendre faux tout le temps. aucune idée pourquoi cela arrive.

les mêmes œuvres contenu dans le code php que le vendeur m'a donné à

<?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); 


?> 

Toute idée de ce que je fais mal ici. J'ai essayé de passer "SHA512", "MD5" tout dans le code C# et retourne encore faux.

+1

Selon la documentation de phpseclib, l'algorithme de hachage par défaut est sha1. Avez-vous essayé celui-là en C#? – Michael

+0

@Michael yeap. cela aussi a donné le même résultat – Aneef

+0

Je me demande si vous pourriez aussi avoir besoin de faire (en PHP) '$ rsa-> setEncryptionMode (CRYPT_RSA_ENCRYPTION_PKCS1);'. Le chiffrement OAEP est ce que phpseclib utilise par défaut. C'est plus sécurisé mais moins utilisé que PKCS1. – neubert

Répondre

2

Eh bien, il semble que le fournisseur n'utilise pas PKCS1, il utilise PSS. Vérifiez cette façon (nécessite Bouncy Castle!):

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

Oui .. je suppose que leur doc et la mise en œuvre semble être diff. merci beaucoup pour l'idée. – Aneef

2

PSS est pris en charge dans la boîte avec .NET 4.6+, mais nécessite l'utilisation de la classe RSACng (CAPI, qui RSACryptoServiceProvider est basé sur, ne offre-le).

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); 
}