Apparently (!) Inconsistent signing between .NET and Mono; Mono signing is not idempotent

Google Cloud Storage provides sample Java, C # code for generating signed URLs:

https://cloud.google.com/storage/docs/access-control?hl=en#signing-code-csharp

I am using sample code. Java code and C # code (on Windows) work with the same service key, key, bucket, and object. When I try to use C # code on Mono / Linux, it does not work. Mistake:

Code: SignatureDoesNotMatch
Message: The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.

Entering some debugging codes confirms this error.

Here is an extended method that performs signing:

private String signString(String stringToSign)  {
    if (key == null) throw new Exception("Certificate not initialized");
    CspParameters cp = new CspParameters(
        24,
        "Microsoft Enhanced RSA and AES Cryptographic Provider",
        ((RSACryptoServiceProvider)key.PrivateKey).CspKeyContainerInfo.KeyContainerName
        );
    RSACryptoServiceProvider provider = new RSACryptoServiceProvider(cp);
    byte[] buffer = Encoding.UTF8.GetBytes(stringToSign);
    byte[] rawSignature = provider.SignData(buffer, CryptoConfig.MapNameToOID("SHA256"));
    Console.WriteLine ("signature == ");
    Console.WriteLine (BitConverter.ToString(rawSignature).Replace("-", string.Empty));
    return Convert.ToBase64String(rawSignature);
}

I expect (possibly wrong) repeated calls to signString with the same string value, will return the same rawSignature and result. On Java and Windows, this is true. In Mono, the value changes

String testString="helloworld";
Console.WriteLine("Signing '" + testString + "' == " + this.signString(testString));
Console.WriteLine("Signing '" + testString + "' == " + this.signString(testString));
Console.WriteLine("Signing '" + testString + "' == " + this.signString(testString));

returns abbreviated results:

signature == 
4415768E8E2FB862...
Signing 'helloworld' == RBV2jo4v...
signature == 
95E589C2F8DAD7ED...
Signing 'helloworld' == leWJwvja...
signature == 
0589E4454FE4FB3A...
Signing 'helloworld' == BYnkRU/k...

Java Google :

rawSignature == 
3E56F09EE9CF7D98...
Signing 'helloworld' == PlbwnunP...
rawSignature == 
3E56F09EE9CF7D98...
Signing 'helloworld' == PlbwnunP...
rawSignature == 
3E56F09EE9CF7D98...
Signing 'helloworld' == PlbwnunP...

?

+4
1

, CspParameters , PrivateKey X509Certificate2. "" , , , , , , Windows Linux ( Mono 4.0.2), , . , Mono:

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

public class Test
{
    static void Main()
    {
        var key = new X509Certificate2("key.p12", "notasecret");
        byte[] buffer = Encoding.UTF8.GetBytes("test string");
        // This is the slightly dodgy bit...
        var rsa = (RSACryptoServiceProvider) key.PrivateKey;
        byte[] signature = rsa.SignData(buffer, "SHA256");
        Console.WriteLine(Convert.ToBase64String(signature));
    }
}

, .NET : (

, , , .

, RSA SignData GetPrivateRSAKey() , RSA:

var rsa = key.GetRSAPrivateKey();
var signature = rsa.SignData(
   buffer, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

, Mono , .

0

Source: https://habr.com/ru/post/1608709/


All Articles