Search code examples
c#cbor

How to COSE sign CBOR binary document using C# .Net core?


How to COSE sign CBOR binary document using C# .Net core? I've found there is NuGet Package Com.AugustCellars.COSE But I'm new to this field and I can't find any examples, how to use it.


Solution

  • Finally I myself came up with working example

    using Com.AugustCellars.COSE;
    using PeterO.Cbor;
    using System;
    using System.Security.Cryptography.X509Certificates;
    
    namespace Example
    {
        class CoseSignExampleClass
        {
    
    
            public void RunCoseSigningExample()
            {
                string exampleJson = "{\"name\":\"example\"}";
                CBORObject exampleCbor = CBORObject.FromJSONString(exampleJson);
                byte[] cborBytes = exampleCbor.EncodeToBytes();
    
    
                // signedCbor now is COSE signed CBOR document
                byte[] signedCbor = CoseSign(cborBytes);
                
    
                // one can check verify signature with public key
                bool validSignature = ValidateCoseSignature(signedCbor);
    
    
                // one can get back document
                byte[] extractedCborBytes = GetCoseContent(signedCbor);
                PeterO.Cbor.CBORObject decodedCborData = PeterO.Cbor.CBORObject.DecodeFromBytes(extractedCborBytes);
    
                string output = decodedCborData.ToString();
            }
    
    
    
            byte[] CoseSign(byte[] cborBytes)
            {
                OneKey signKeyPrivate = GetSignPrivateKey();
    
                Sign1Message signMessage = new Sign1Message();
                signMessage.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.ECDSA_256, Attributes.PROTECTED);
    
                signMessage.SetContent(cborBytes);
    
                signMessage.Sign(signKeyPrivate);
                byte[] rgbMsg = signMessage.EncodeToBytes();
    
                return rgbMsg;
            }
    
            static OneKey GetSignPrivateKey()
            {
                /* 
                 * privateKeyString is PKCS8 key without starting and ending tags
                 * "-----BEGIN PRIVATE KEY-----"
                 * "-----END PRIVATE KEY-----"
                 */
    
                string privateKeyString = @"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgfK2MnqJPUzuSy2tB
    t7kjH5OGeP8O38dkOMXmKNfVynuhRANCAASPTR2m+kV/3Xuxh8tjRxJn0v//Y/yS
    Tl+LHlBowq7v+i6sGpJXEfPYbBc+tGZBL9MXX6WMV1I0QCMykqLyKwD3";
    
                byte[] Pkcs8PrivateKey = Convert.FromBase64String(privateKeyString);
                OneKey cnKeyPrivate = OneKey.FromPkcs8(Pkcs8PrivateKey);
    
                return cnKeyPrivate;
            }
    
            byte[] GetCoseContent(byte[] coseDocument)
            {
                Sign1Message msg = (Sign1Message)Message.DecodeFromBytes(coseDocument, Tags.Sign1);
                return msg.GetContent();
            }
    
            bool ValidateCoseSignature(byte[] coseDocument)
            {
                Sign1Message msg = (Sign1Message)Message.DecodeFromBytes(coseDocument, Tags.Sign1);
                OneKey cnKeyPublic = GetSignPublicKey();
                return msg.Validate(cnKeyPublic);
            }
    
            static OneKey GetSignPublicKey()
            {
                /* 
                 * publicKeyString is Pem public cert without starting and ending tags
                 * "-----BEGIN CERTIFICATE-----"
                 * "-----END CERTIFICATE-----"
                 */
    
                string publicKeyString = @"MIICTzCCAfWgAwIBAgIUJgt2piBt1qKUVWqjs/bhkSTpbscwCgYIKoZIzj0EAwIw
    ZDELMAkGA1UEBhMCTFYxLTArBgNVBAoMJE5hY2lvbsOEwoFsYWlzIFZlc2Vsw4TC
    q2JhcyBkaWVuZXN0czEMMAoGA1UECwwDVExTMRgwFgYDVQQDDA9UTFMgREdDIExW
    IFRlc3QwHhcNMjEwNTE4MTA0OTA1WhcNMjMwNTE4MTA0OTA1WjBkMQswCQYDVQQG
    EwJMVjEtMCsGA1UECgwkTmFjaW9uw4TCgWxhaXMgVmVzZWzDhMKrYmFzIGRpZW5l
    c3RzMQwwCgYDVQQLDANUTFMxGDAWBgNVBAMMD1RMUyBER0MgTFYgVGVzdDBZMBMG
    ByqGSM49AgEGCCqGSM49AwEHA0IABI9NHab6RX/de7GHy2NHEmfS//9j/JJOX4se
    UGjCru/6LqwaklcR89hsFz60ZkEv0xdfpYxXUjRAIzKSovIrAPejgYQwgYEwDgYD
    VR0PAQH/BAQDAgeAMB0GA1UdDgQWBBQO528ONBxapB+St9et1oYQySBhjjA3BgNV
    HR8EMDAuMCygKqAohiZodHRwOi8vY3JsLm5wa2QubmwvQ1JMcy9OTEQtSGVhbHRo
    LmNybDAXBgNVHSUEEDAOBgwrBgEEAQCON49lAQEwCgYIKoZIzj0EAwIDSAAwRQIg
    Bc50+qIVI+IUQrUJQdYywW1PhNEyW5VxiT3HvGxyJaACIQD+ze+4r5GUcuWdNpPP
    lFcSLRBj/MNpO6sl8h2Y5h/c8g==";
    
                byte[] publicKeyData = Convert.FromBase64String(publicKeyString);
    
                byte[] certData;
    
                using (X509Certificate2 x509Cert = new X509Certificate2(publicKeyData))
                    certData = x509Cert.GetRawCertData();
    
    
                OneKey keyPublic = OneKey.FromX509(certData);
    
                return keyPublic;
            }
        }
    }