Проверьте подпись обратного вызова Google Wallet с C# (без внешних библиотек) ⇐ C#

Место общения программистов C#
Anonymous
Проверьте подпись обратного вызова Google Wallet с C# (без внешних библиотек)

Сообщение Anonymous »

При использовании Google Wallet API можно предоставить URL -адрес обратного вызова, это будет указывать, был ли проход был добавлен или удален из пользователя. Криптография данных и адаптация с помощью Google Wallet API - добавить и удалить обратные вызовы. < /p>
Ниже приведен код, который я написал до сих пор. Обратите внимание, что VerifyInterMediateSignature () уже возвращает отрицательный результат.
Любая помощь очень ценится!public bool VerifyCallbackSignatures(CallbackBody? callbackBody)
{
if (callbackBody == null)
return false;

// BUILD INTERMEDIATE SIGNATURE
// signedStringForIntermediateSigningKeySignature =
// length_of_sender_id || sender_id || length_of_protocol_version || protocol_version || length_of_signed_key || signed_key

// JsonCanonicalizer.Canonicalize() returns the same string given as input, just in the right order. (I tried also without it).
string signedKeyString = JsonCanonicalizer.Canonicalize(callbackBody.IntermediateSigningKey.SignedKey);

string senderId = "GooglePayPasses"; // Fixed
byte[] signedStringForIntermediateSigningKeySignature =
[
.. GetLengthRepresentation(senderId),
.. Encoding.UTF8.GetBytes(senderId),
.. GetLengthRepresentation(callbackBody.ProtocolVersion),
.. Encoding.UTF8.GetBytes(callbackBody.ProtocolVersion),
.. GetLengthRepresentation(signedKeyString),
.. Encoding.UTF8.GetBytes(signedKeyString),
];

// COMPARE INTERMEDIATE SIGNATURE
bool result = VerifyIntermediateSignature(callbackBody, signedStringForIntermediateSigningKeySignature);

if (result == false)
return false;

// signedStringForMessageSignature =
// length_of_sender_id || sender_id || length_of_recipient_id || recipient_id || length_of_protocolVersion || protocolVersion || length_of_signedMessage || signedMessage

string signedMessageString = JsonCanonicalizer.Canonicalize(callbackBody.SignedMessage);

byte[] signedStringForMessageSignature =
[
.. GetLengthRepresentation(senderId),
.. Encoding.UTF8.GetBytes(senderId),
.. GetLengthRepresentation(Constants.IssuerId),
.. Encoding.UTF8.GetBytes(Constants.IssuerId),
.. GetLengthRepresentation(callbackBody.ProtocolVersion),
.. Encoding.UTF8.GetBytes(callbackBody.ProtocolVersion),
.. GetLengthRepresentation(signedMessageString),
.. Encoding.UTF8.GetBytes(signedMessageString)
];

result = VerifyMessageSignature(callbackBody, signedStringForMessageSignature);
if (result == false)
return false;

return true;
}

// --------------------------------------------------------------------------------------

private bool VerifyIntermediateSignature(CallbackBody callbackBody, byte[] dataBytes)
{
foreach (GooglePublicKey googleKey in _googleKeys.Keys)
{
// Parse the public key from base64
byte[] publicKeyBytes = Convert.FromBase64String(googleKey.KeyValue);

using ECDsa ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256);
ecdsa.ImportSubjectPublicKeyInfo(publicKeyBytes, out _);

foreach (string internalSignature in callbackBody.IntermediateSigningKey.Signatures)
{
// Get the signature from the callback body (assuming it's base64 encoded)
byte[] signatureBytes = Convert.FromBase64String(internalSignature);

if (ecdsa.VerifyData(dataBytes, signatureBytes, HashAlgorithmName.SHA256))
{
return true;
}

}
}
return false;
}

private bool VerifyMessageSignature(CallbackBody callbackBody, byte[] dataBytes)
{
byte[] keyBytes = Convert.FromBase64String(callbackBody.IntermediateSigningKey.SignedKeyObject.KeyValue);
using ECDsa ecdsa = ECDsa.Create();
ecdsa.ImportSubjectPublicKeyInfo(keyBytes, out _);

byte[] signatureBytes = Convert.FromBase64String(callbackBody.Signature);

return ecdsa.VerifyData(dataBytes, signatureBytes, HashAlgorithmName.SHA256);
}

///
/// Transforms integer length into the desired representation: 4 bytes in little endian format.
///
///
///
private byte[] GetLengthRepresentation(string str)
{
byte[] strBytes = Encoding.UTF8.GetBytes(str);
byte[] bytes = BitConverter.GetBytes(strBytes.Length);

return bytes;
}


Подробнее здесь: https://stackoverflow.com/questions/796 ... -libraries

Вернуться в «C#»