且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用 Json 文件进行 Google 服务帐户身份验证

更新时间:2023-12-03 09:55:28

刚刚意识到这是多久以前的报道.我猜你找到了答案或放弃了.

您的代码现在可以工作了 - 我在 BouncyCastle 1.8.1 上试过了,它可以工作,但在 1.7.0 上却失败了.

使用的代码:

使用系统;使用 System.Security.Cryptography;使用 Newtonsoft.Json;使用 Org.BouncyCastle.Crypto.Parameters;使用 Org.BouncyCastle.Security;命名空间 ConsoleApp1{课程计划{public static void Main(){var json = "{"private_key_id":"xxxxxx","private_key":"-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDcmuyQC8rwWdPQsJFASCBYGKDcmuyQC8rwWdPQs\JQBypGmX5\GFBYGWZYPQ\JQBypGxypqsfbgrwwdpqsfbgrwwdpqsfbgwgrwdpqsjfbycypgrwwdpqsjbrybgrwgxypqsnfS1X1/PCpPVpTCA4749K8gbvuZg1JEIAqMtmHiBBrJj5l8eiekQc8pd7Pq35H4wi \ nJYXAJGwggPcttkLBRi0xZzd + jdwL1st + 7zRt8nMao/xFibInBBvKwb/gP4mJxlQg \ nnRdGO6zgMk + PLTcA5C + gFyPA4SdkylrLib5CJO9123FgcfTJZJTukeHo1v0EfU + 4 \ n3bK8HBZnOFa4DHH4mXhkhgYMjibv4Sr/WCEoomJJwNN04SbUEdyhgpM2rZ3cvx + 4 \ nsmB0SQflAgMBAAECggEAXZ100 +/++ DL7 zh9cHVQdcrRDzprBplw3H/bjg7wdgftN \ n7Wgm5214YQKNG6HSWORjqC9oX/+ agZYs8w69xjBDJg9ggU2nwuGOGky4utQ0jiCT \ nzbnTjsMsBxKaXBiXxBBEhVBBDjDcHQLRMdBggNgz9lskCYb1rxT7qqJVf2PtxCuZ \ nuxw3whLMRHXvKosER12sMQgGB/0 + Nk86GWCqPigpfu7Ec92V0ffcSUaq3gjIUD54 \ n67TduTWaRDQNB + j2yQsWQZnqRv + TvIXOjinAI + pPbvCUovtiTSZAoz3EalsiXQ0l \ nUqDVx26uzEJqhB2kzvAeApuW2Nd5EPxUnf48c4xh4QKBgQDw01mEChWyENV5CBKU \ nMSfY0rpAPtq7ahHRR458ZKtITDBlqiZLMjydI65Rr1XxpQ3pJZALObMdUhbvCDfm \ nu4BY/LCCT + hcdt9IICvVZsgXgvb6M + Fj2IbYZcAnOm4T1Z1D3I + pW5NdK2ALQRiK \ nWsGINOqWCB9WRd7nhmb/XwWyjQKBgQDqgWht5laDuLMc4qpj9finY4qmk57eT3KG \ npzbVlT3h7kv7j/J6E + 6o9psrqdf1PXpu9XZi3bPtPbH1fX9x5pZgJQRMP4FGOURY \ nQDkJfiOOSN/8Vl0senqkscT7DSbe2BqyqQlSlTB4BBF29p1wxb5Wz5HH2BvYE2zI \ ni9B4WJcAuQKBgADnajCasRYoBgUcSKWRwaqIr/ZJxhxp + 4Mjl59T6WiuEIhxKQ + J \ nMqMMXT0lQVdU3UaAw5enMcrsYfWnvD37ejHbUoYLFq4yLAhjRobYieu8rByoUTJE \ nv8zUJPKAv6UHaj20 + D0UgOsanJOuPN9YE93lBPRnN2blgD6yPHS88JKJAoGABFyh \ n16F4LH0L/9aLes6BcIOeeZi3VMU/iRelInXjL8eh7CzyYZ5agxQLMNW46ZvaIiQ4 \ nroAXL6t9GubZrwGt/F3T5aMswWShS87uAKoy +RuL5wKoOwKQM24HDvBgr7ZvULFq \ nNfoGa8UPmhneNdHHx4 + W05PGeM9rr5NCLmrfbCkCgYA0nMvEDIJvU3KA3S1cQ3fs \ nVopRJwqRIFFL1cHTWaEyIsxEh6i/zAUc/habK82dN3/ZDN/XvWY14k7VZPsSdDC9 \ noVlQj2z8DVO2K99Oxyh0VlthtecW8exjzkIPJL4srOSl/dooQZS/7ZZyaRQU/BLI \ nMdzKHlUKKXWcUU + Ko8W4 + W == \ñ----- END PRIVATE KEY -----\n","client_email":"dddddd-2a1f881e7rabfkt2eb1p84aisg30pedg@developer.gserviceaccount.com","client_id":"ddddd-2a1f881e7rabfkt2eb1p84aisg.com","类型":"service_account"}";动态 jsonObject = JsonConvert.DeserializeObject(json);var rsaParams = ConvertPKCS8ToRSAParameters((string)jsonObject.private_key);RSACryptoServiceProvider 密钥 = 新的 RSACryptoServiceProvider();key.ImportParameters(rsaParams);Console.WriteLine($"密钥大小:{key.KeySize},DP:{rsaParams.DP.Length}");Console.ReadLine();}private const string PrivateKeyPrefix = "-----BEGIN PRIVATE KEY-----";private const string PrivateKeySuffix = "-----END PRIVATE KEY-----";/// 将 PKCS8 私钥转换为 RSA 参数.此方法使用 Bouncy Castle 库.</summary>私有静态 RSAParameters ConvertPKCS8ToRSAParameters(字符串 pkcs8PrivateKey){var base64PrivateKey = pkcs8PrivateKey.Replace(PrivateKeyPrefix, "").Replace("
", "").Replace(PrivateKeySuffix, "");var privateKeyBytes = Convert.FromBase64String(base64PrivateKey);RsaPrivateCrtKeyParameters crtParameters = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(privateKeyBytes);返回 DotNetUtilities.ToRSAParameters(crtParameters);}}}

I have been following the Oauth2 Service account documentation on Googles website. I have also been picking apart Googles .net client libray trying to get this to work.

I have reached the Computing the signature stage.

The privacy key from Google looks like this

-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDcmuyQC8rwWdPQ
mIdksgzSJbVWTU5MeUxy+HAap3yut9wR/L6KGMJ4FBYcsPmXN5gQAhErybavGoZG
fS1X1/PCpPVpTCA4749K8gbvuZg1JEIAqMtmHiBBrJj5l8eiekQc8pd7Pq35H4wi
JYXAJGwggPcttkLBRi0xZzd+jdwL1st+7zRt8nMao/xFibInBBvKwb/gP4mJxlQg
nRdGO6zgMk+PLTcA5C+gFyPA4SdkylrLib5CJO9123FgcfTJZJTukeHo1v0EfU+4
3bK8HBZnOFa4DHH4mXhkhgYMjibv4Sr/WCEoomJJwNN04SbUEdyhgpM2rZ3cvx+4
smB0SQflAgMBAAECggEAXZ100+/dL7++zh9cHVQdcrRDzprBplw3H/bjg7wdgftN
7Wgm5214YQKNG6HSWORjqC9oX/+agZYs8w69xjBDJg9ggU2nwuGOGky4utQ0jiCT
zbnTjsMsBxKaXBiXxBBEhVBBDjDcHQLRMdBggNgz9lskCYb1rxT7qqJVf2PtxCuZ
uxw3whLMRHXvKosER12sMQgGB/0+Nk86GWCqPigpfu7Ec92V0ffcSUaq3gjIUD54
67TduTWaRDQNB+j2yQsWQZnqRv+TvIXOjinAI+pPbvCUovtiTSZAoz3EalsiXQ0l
UqDVx26uzEJqhB2kzvAeApuW2Nd5EPxUnf48c4xh4QKBgQDw01mEChWyENV5CBKU
MSfY0rpAPtq7ahHRR458ZKtITDBlqiZLMjydI65Rr1XxpQ3pJZALObMdUhbvCDfm
u4BY/lCCt+hcdt9IICvVZsgXgvb6M+Fj2IbYZcAnOm4T1Z1D3I+pW5NdK2ALQRiK
WsGINOqWCB9WRd7nhmb/XwWyjQKBgQDqgWht5laDuLMc4qpj9finY4qmk57eT3KG
pzbVlT3h7kv7j/j6e+6o9psrqdf1PXpu9XZi3bPtPbH1fX9x5pZgJQRMP4FGOURY
QDkJfiOOSN/8Vl0senqkscT7DSbe2BqyqQlSlTB4BBF29p1wxb5Wz5HH2BvYE2zI
i9B4WJcAuQKBgADnajCasRYoBgUcSKWRwaqIr/ZJxhxp+4Mjl59T6WiuEIhxKQ+j
MqMMXT0lQVdU3UaAw5enMcrsYfWnvD37ejHbUoYLFq4yLAhjRobYieu8rByoUTJE
v8zUJPKAv6UHaj20+D0UgOsanJOuPN9YE93lBPRnN2blgD6yPHS88JKJAoGABFyh
16F4LH0L/9aLes6BcIOeeZi3VMU/iRelInXjL8eh7CzyYZ5agxQLMNW46ZvaIiQ4
roAXL6t9GubZrwGt/F3T5aMswWShS87uAKoy+RuL5wKoOwKQM24HDvBgr7ZvULFq
NfoGa8UPmhneNdHHx4+W05PGeM9rr5NCLmrfbCkCgYA0nMvEDIJvU3KA3S1cQ3fs
VopRJwqRIFFL1cHTWaEyIsxEh6i/zAUc/habK82dN3/ZDn/XvWY14k7VZPsSdDC9
oVlQj2z8DVO2K99Oxyh0VlthtecW8exjzkIPJL4srOSl/dooQZS/7ZZyaRQU/BLI
MdzKHlUKKXWcUU+Ko8W4+wu003du003d
-----END PRIVATE KEY-----

Clean up key

First I clean up the key a bit

private const string PrivateKeyPrefix = "-----BEGIN PRIVATE KEY-----";
private const string PrivateKeySuffix = "-----END PRIVATE KEY-----";

 /// <summary>Converts the PKCS8 private key to RSA parameters. This method uses the Bouncy Castle library.</summary>
        private static RSAParameters ConvertPKCS8ToRSAParameters(string pkcs8PrivateKey)
        {

            var base64PrivateKey = pkcs8PrivateKey.Replace(PrivateKeyPrefix, "").Replace("
", "").Replace(PrivateKeySuffix, "");           
            var privateKeyBytes = Convert.FromBase64String(base64PrivateKey);
            RsaPrivateCrtKeyParameters crtParameters = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(privateKeyBytes);           


            return DotNetUtilities.ToRSAParameters(crtParameters);
        }

Import Parameters

 RSAParameters rsaParameters = ConvertPKCS8ToRSAParameters(results.private_key);
 RSACryptoServiceProvider key = new RSACryptoServiceProvider();
 key.ImportParameters(rsaParameters);

Error

'System.Security.Cryptography.CryptographicException' occurred in mscorlib.dll

Additional information: Bad Data.

My ideas

the dp value seams to be off everything I have read says it should be 128 bytes not 127.

Note:

I am not using the p12. file I am using the Json service account file. Answers using the X509Certificate2 and the p12 key file will not help.

{
  "private_key_id": "xxxxxx",
  "private_key": "-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDcmuyQC8rwWdPQ
mIdksgzSJbVWTU5MeUxy+HAap3yut9wR/L6KGMJ4FBYcsPmXN5gQAhErybavGoZG
fS1X1/PCpPVpTCA4749K8gbvuZg1JEIAqMtmHiBBrJj5l8eiekQc8pd7Pq35H4wi
JYXAJGwggPcttkLBRi0xZzd+jdwL1st+7zRt8nMao/xFibInBBvKwb/gP4mJxlQg
nRdGO6zgMk+PLTcA5C+gFyPA4SdkylrLib5CJO9123FgcfTJZJTukeHo1v0EfU+4
3bK8HBZnOFa4DHH4mXhkhgYMjibv4Sr/WCEoomJJwNN04SbUEdyhgpM2rZ3cvx+4
smB0SQflAgMBAAECggEAXZ100+/dL7++zh9cHVQdcrRDzprBplw3H/bjg7wdgftN
7Wgm5214YQKNG6HSWORjqC9oX/+agZYs8w69xjBDJg9ggU2nwuGOGky4utQ0jiCT
zbnTjsMsBxKaXBiXxBBEhVBBDjDcHQLRMdBggNgz9lskCYb1rxT7qqJVf2PtxCuZ
uxw3whLMRHXvKosER12sMQgGB/0+Nk86GWCqPigpfu7Ec92V0ffcSUaq3gjIUD54
67TduTWaRDQNB+j2yQsWQZnqRv+TvIXOjinAI+pPbvCUovtiTSZAoz3EalsiXQ0l
UqDVx26uzEJqhB2kzvAeApuW2Nd5EPxUnf48c4xh4QKBgQDw01mEChWyENV5CBKU
MSfY0rpAPtq7ahHRR458ZKtITDBlqiZLMjydI65Rr1XxpQ3pJZALObMdUhbvCDfm
u4BY/lCCt+hcdt9IICvVZsgXgvb6M+Fj2IbYZcAnOm4T1Z1D3I+pW5NdK2ALQRiK
WsGINOqWCB9WRd7nhmb/XwWyjQKBgQDqgWht5laDuLMc4qpj9finY4qmk57eT3KG
pzbVlT3h7kv7j/j6e+6o9psrqdf1PXpu9XZi3bPtPbH1fX9x5pZgJQRMP4FGOURY
QDkJfiOOSN/8Vl0senqkscT7DSbe2BqyqQlSlTB4BBF29p1wxb5Wz5HH2BvYE2zI
i9B4WJcAuQKBgADnajCasRYoBgUcSKWRwaqIr/ZJxhxp+4Mjl59T6WiuEIhxKQ+j
MqMMXT0lQVdU3UaAw5enMcrsYfWnvD37ejHbUoYLFq4yLAhjRobYieu8rByoUTJE
v8zUJPKAv6UHaj20+D0UgOsanJOuPN9YE93lBPRnN2blgD6yPHS88JKJAoGABFyh
16F4LH0L/9aLes6BcIOeeZi3VMU/iRelInXjL8eh7CzyYZ5agxQLMNW46ZvaIiQ4
roAXL6t9GubZrwGt/F3T5aMswWShS87uAKoy+RuL5wKoOwKQM24HDvBgr7ZvULFq
NfoGa8UPmhneNdHHx4+W05PGeM9rr5NCLmrfbCkCgYA0nMvEDIJvU3KA3S1cQ3fs
VopRJwqRIFFL1cHTWaEyIsxEh6i/zAUc/habK82dN3/ZDn/XvWY14k7VZPsSdDC9
oVlQj2z8DVO2K99Oxyh0VlthtecW8exjzkIPJL4srOSl/dooQZS/7ZZyaRQU/BLI
MdzKHlUKKXWcUU+Ko8W4+wu003du003d
-----END PRIVATE KEY-----
",
  "client_email": "dddddd-2a1f881e7rabfkt2eb1p84aisg30pedg@developer.gserviceaccount.com",
  "client_id": "ddddd-2a1f881e7rabfkt2eb1p84aisg30pedg.apps.googleusercontent.com",
  "type": "service_account"
}

Just realised how long ago this was reported. I presume you found an answer or gave up.

Your code now works - I tried this on BouncyCastle 1.8.1 and it works, it fails on 1.7.0.

Code used:

using System;
using System.Security.Cryptography;
using Newtonsoft.Json;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;

namespace ConsoleApp1
{
    class Program
    {
        public static void Main()
        {
            var json = "{"private_key_id":"xxxxxx","private_key":"-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDcmuyQC8rwWdPQ\nmIdksgzSJbVWTU5MeUxy+HAap3yut9wR/L6KGMJ4FBYcsPmXN5gQAhErybavGoZG\nfS1X1/PCpPVpTCA4749K8gbvuZg1JEIAqMtmHiBBrJj5l8eiekQc8pd7Pq35H4wi\nJYXAJGwggPcttkLBRi0xZzd+jdwL1st+7zRt8nMao/xFibInBBvKwb/gP4mJxlQg\nnRdGO6zgMk+PLTcA5C+gFyPA4SdkylrLib5CJO9123FgcfTJZJTukeHo1v0EfU+4\n3bK8HBZnOFa4DHH4mXhkhgYMjibv4Sr/WCEoomJJwNN04SbUEdyhgpM2rZ3cvx+4\nsmB0SQflAgMBAAECggEAXZ100+/dL7++zh9cHVQdcrRDzprBplw3H/bjg7wdgftN\n7Wgm5214YQKNG6HSWORjqC9oX/+agZYs8w69xjBDJg9ggU2nwuGOGky4utQ0jiCT\nzbnTjsMsBxKaXBiXxBBEhVBBDjDcHQLRMdBggNgz9lskCYb1rxT7qqJVf2PtxCuZ\nuxw3whLMRHXvKosER12sMQgGB/0+Nk86GWCqPigpfu7Ec92V0ffcSUaq3gjIUD54\n67TduTWaRDQNB+j2yQsWQZnqRv+TvIXOjinAI+pPbvCUovtiTSZAoz3EalsiXQ0l\nUqDVx26uzEJqhB2kzvAeApuW2Nd5EPxUnf48c4xh4QKBgQDw01mEChWyENV5CBKU\nMSfY0rpAPtq7ahHRR458ZKtITDBlqiZLMjydI65Rr1XxpQ3pJZALObMdUhbvCDfm\nu4BY/lCCt+hcdt9IICvVZsgXgvb6M+Fj2IbYZcAnOm4T1Z1D3I+pW5NdK2ALQRiK\nWsGINOqWCB9WRd7nhmb/XwWyjQKBgQDqgWht5laDuLMc4qpj9finY4qmk57eT3KG\npzbVlT3h7kv7j/j6e+6o9psrqdf1PXpu9XZi3bPtPbH1fX9x5pZgJQRMP4FGOURY\nQDkJfiOOSN/8Vl0senqkscT7DSbe2BqyqQlSlTB4BBF29p1wxb5Wz5HH2BvYE2zI\ni9B4WJcAuQKBgADnajCasRYoBgUcSKWRwaqIr/ZJxhxp+4Mjl59T6WiuEIhxKQ+j\nMqMMXT0lQVdU3UaAw5enMcrsYfWnvD37ejHbUoYLFq4yLAhjRobYieu8rByoUTJE\nv8zUJPKAv6UHaj20+D0UgOsanJOuPN9YE93lBPRnN2blgD6yPHS88JKJAoGABFyh\n16F4LH0L/9aLes6BcIOeeZi3VMU/iRelInXjL8eh7CzyYZ5agxQLMNW46ZvaIiQ4\nroAXL6t9GubZrwGt/F3T5aMswWShS87uAKoy+RuL5wKoOwKQM24HDvBgr7ZvULFq\nNfoGa8UPmhneNdHHx4+W05PGeM9rr5NCLmrfbCkCgYA0nMvEDIJvU3KA3S1cQ3fs\nVopRJwqRIFFL1cHTWaEyIsxEh6i/zAUc/habK82dN3/ZDn/XvWY14k7VZPsSdDC9\noVlQj2z8DVO2K99Oxyh0VlthtecW8exjzkIPJL4srOSl/dooQZS/7ZZyaRQU/BLI\nMdzKHlUKKXWcUU+Ko8W4+w==\n-----END PRIVATE KEY-----\n","client_email":"dddddd-2a1f881e7rabfkt2eb1p84aisg30pedg@developer.gserviceaccount.com","client_id":"ddddd-2a1f881e7rabfkt2eb1p84aisg30pedg.apps.googleusercontent.com","type":"service_account"}";

            dynamic jsonObject = JsonConvert.DeserializeObject(json);

            var rsaParams = ConvertPKCS8ToRSAParameters((string)jsonObject.private_key);

            RSACryptoServiceProvider key = new RSACryptoServiceProvider();
            key.ImportParameters(rsaParams);

            Console.WriteLine($"Key size: {key.KeySize}, DP: {rsaParams.DP.Length}");
            Console.ReadLine();
        }

        private const string PrivateKeyPrefix = "-----BEGIN PRIVATE KEY-----";
        private const string PrivateKeySuffix = "-----END PRIVATE KEY-----";

        /// <summary>Converts the PKCS8 private key to RSA parameters. This method uses the Bouncy Castle library.</summary>
        private static RSAParameters ConvertPKCS8ToRSAParameters(string pkcs8PrivateKey)
        {

            var base64PrivateKey = pkcs8PrivateKey.Replace(PrivateKeyPrefix, "").Replace("
", "").Replace(PrivateKeySuffix, "");
            var privateKeyBytes = Convert.FromBase64String(base64PrivateKey);
            RsaPrivateCrtKeyParameters crtParameters = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(privateKeyBytes);


            return DotNetUtilities.ToRSAParameters(crtParameters);
        }
    }
}