diff --git a/src/CryptoAgent/CryptoAgent.csproj b/src/CryptoAgent/CryptoAgent.csproj index 7720812..b18271c 100644 --- a/src/CryptoAgent/CryptoAgent.csproj +++ b/src/CryptoAgent/CryptoAgent.csproj @@ -12,6 +12,7 @@ + diff --git a/src/CryptoAgent/CryptoAgentSettings.cs b/src/CryptoAgent/CryptoAgentSettings.cs index 1383255..4a27a84 100644 --- a/src/CryptoAgent/CryptoAgentSettings.cs +++ b/src/CryptoAgent/CryptoAgentSettings.cs @@ -36,7 +36,12 @@ public string AzureKeyvaultAdTenantId { get; set; } public string AzureKeyvaultAdAppId { get; set; } public string AzureKeyvaultAdSecret { get; set; } - // GCP... + // Google Cloud KMS + public string GoogleCloudProjectId { get; set; } + public string GoogleCloudLocationId { get; set; } + public string GoogleCloudKeyringId { get; set; } + public string GoogleCloudKeyId { get; set; } + public string GoogleCloudKeyVersionId { get; set; } // AWS... // Hashicorp Vault... // Other HSMs... diff --git a/src/CryptoAgent/Services/GoogleCloudKmsRsaKeyService.cs b/src/CryptoAgent/Services/GoogleCloudKmsRsaKeyService.cs new file mode 100644 index 0000000..e5b47b9 --- /dev/null +++ b/src/CryptoAgent/Services/GoogleCloudKmsRsaKeyService.cs @@ -0,0 +1,77 @@ +using Google.Cloud.Kms.V1; +using Google.Protobuf; +using System; +using System.Security.Cryptography; +using System.Threading.Tasks; + +namespace Bit.CryptoAgent.Services +{ + public class GoogleCloudKmsRsaKeyService : IRsaKeyService + { + private readonly KeyManagementServiceClient _keyManagementServiceClient; + private readonly CryptoKeyName _cryptoKeyName; + private readonly CryptoKeyVersionName _cryptoKeyVersionName; + + public GoogleCloudKmsRsaKeyService( + CryptoAgentSettings settings) + { + _keyManagementServiceClient = KeyManagementServiceClient.Create(); + _cryptoKeyName = new CryptoKeyName(settings.RsaKey.GoogleCloudProjectId, + settings.RsaKey.GoogleCloudLocationId, settings.RsaKey.GoogleCloudKeyringId, + settings.RsaKey.GoogleCloudKeyId); + _cryptoKeyVersionName = new CryptoKeyVersionName(settings.RsaKey.GoogleCloudProjectId, + settings.RsaKey.GoogleCloudLocationId, settings.RsaKey.GoogleCloudKeyringId, + settings.RsaKey.GoogleCloudKeyId, settings.RsaKey.GoogleCloudKeyVersionId); + } + + public async Task EncryptAsync(byte[] data) + { + var result = await _keyManagementServiceClient.EncryptAsync(_cryptoKeyName, ByteString.CopyFrom(data)); + return result.Ciphertext.ToByteArray(); + + } + + public async Task DecryptAsync(byte[] data) + { + var result = await _keyManagementServiceClient.DecryptAsync(_cryptoKeyName, ByteString.CopyFrom(data)); + return result.Plaintext.ToByteArray(); + } + + public async Task SignAsync(byte[] data) + { + using var sha256 = SHA256.Create(); + var hash = sha256.ComputeHash(data); + var digest = new Digest + { + Sha256 = ByteString.CopyFrom(hash) + }; + var result = await _keyManagementServiceClient.AsymmetricSignAsync(_cryptoKeyVersionName, digest); + return result.Signature.ToByteArray(); + } + + public async Task VerifyAsync(byte[] data, byte[] signature) + { + using var sha256 = SHA256.Create(); + var hash = sha256.ComputeHash(data); + var rsa = await GetRsaPublicKeyAsync(); + var verified = rsa.VerifyHash(hash, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + return verified; + } + + public async Task GetPublicKeyAsync() + { + var rsa = await GetRsaPublicKeyAsync(); + return rsa.ExportRSAPublicKey(); + } + + public async Task GetRsaPublicKeyAsync() + { + var publicKey = await _keyManagementServiceClient.GetPublicKeyAsync(_cryptoKeyVersionName); + var blocks = publicKey.Pem.Split("-", StringSplitOptions.RemoveEmptyEntries); + var pem = Convert.FromBase64String(blocks[1]); + var rsa = RSA.Create(); + rsa.ImportSubjectPublicKeyInfo(pem, out _); + return rsa; + } + } +}