如何使用 HashiCorp Vault 签名
How do I sign with HashiCorp Vault
我不知道这个问题是否很简单,我只是没有弄清楚如何与 HashiCorp-Vault 的 Api VaultSharp 签约,但我很绝望。
可在此处找到包含示例的完整文档:https://github.com/rajanadar/VaultSharp
加密和解密工作正常。只有签名是个问题。
加密代码:
public byte[] EncryptData(byte[] data, string keyName)
{
SecretsEngine transitSecretsEngine = new SecretsEngine
{
Type = SecretsEngineType.Transit,
Path = path
};
Client.V1.System.MountSecretBackendAsync(transitSecretsEngine).Wait();
Client.V1.Secrets.Transit.CreateEncryptionKeyAsync(keyName, new CreateKeyRequestOptions()
{
Exportable = true
}, path).Wait();
EncryptRequestOptions encryptOptions = new EncryptRequestOptions
{
Base64EncodedPlainText = Convert.ToBase64String(data),
ConvergentEncryption = true,
};
Secret<EncryptionResponse> encryptionResponse = Client.V1.Secrets.Transit.EncryptAsync(keyName,
encryptOptions, path).Result;
string cipherText = encryptionResponse.Data.CipherText;
return Encoding.Unicode.GetBytes(cipherText);
}
解密代码:
public byte[] DecryptData(string ciphertext, string keyName)
{
DecryptRequestOptions decryptOptions = new DecryptRequestOptions
{
CipherText = ciphertext,
};
Secret<DecryptionResponse> decryptionResponse = Client.V1.Secrets.Transit.DecryptAsync(keyName,
decryptOptions, path).Result;
return Convert.FromBase64String(decryptionResponse.Data.Base64EncodedPlainText);
}
这是我的签名代码试用版:
public byte[] Sign(byte[] plaintextBytes, string keyName)
{
byte[] hash = ComputeHash(plaintextBytes,SHA256.Create());
GCKMS.SignatureOptions options = new GCKMS.SignatureOptions()
{
Digest = Convert.ToBase64String(hash),
};
Secret<GCKMS.SignatureResponse> result = Client.V1.Secrets.GoogleCloudKMS.SignAsync(keyName,
options).Result;
return Encoding.Unicode.GetBytes(result.Data.Signature);
}
错误是:
VaultSharp.Core.VaultApiException: {"errors":["no handler for route
'gcpkms/sign/Manuel'"]}
最后但同样重要的是我的签名验证代码:
public bool ValidateSignature(byte[] plaintextByte, byte[] signature, string keyName)
{
GCKMS.VerificationOptions option = new GCKMS.VerificationOptions
{
Digest = Encoding.Unicode.GetString(ComputeHash(plaintextByte)),
Signature = Encoding.Unicode.GetString(signature)
};
Secret<GCKMS.VerificationResponse> result =
Client.V1.Secrets.GoogleCloudKMS.VerifyAsync(keyName, option).Result;
return result.Data.Valid;
}
我不确定,但这可能是因为我没有使用带路径的 SecretsEngine。我找不到任何适用于 GoogleCloudKms 的 SecretsEngine。
有用信息:
我用 Guid.NewGuid().ToString();
生成路径。
ComputeHash 是一个自写的函数,它使用给定的算法计算哈希值。这
默认算法是 SHA256。
GCMS 是命名空间的简短版本 VaultSharp.V1.SecretsEngines.GoogleCloudKMS
非常欢迎任何想法和建议。
提前致谢!
虽然 Vault 提供了方便的 Transit 签名,C# wrapper you are using does not support it。
Google KMS 确实提供签名,但它的接口更复杂:您必须自己进行哈希并跟踪密钥版本。
我建议你在 API 包装器上玩个把戏:
- 留下你的加解密密码as-is
- 写入 Transit 后端就好像它是 KV 存储版本 1
- 通过sending your payload as the
input
parameter 获得您的签名
在将数据发送到 Vault 之前,您仍然需要对其进行 base64,以避免二进制编码问题。
所以假设:
- 您想签署文本
Whosebug
- 传输 back-end 安装在
transit
下
- 您的签名密钥被命名为
my-key
这应该让你开始:
var value = new Dictionary<string, object> { "input", Convert.ToBase64String(Encoding.UTF8.GetBytes("Whosebug")) } };
var writtenValue = await vaultClient.V1.Secrets.KeyValue.V1.WriteSecretAsync("sign/my-key", value, "transit");
我不知道这个问题是否很简单,我只是没有弄清楚如何与 HashiCorp-Vault 的 Api VaultSharp 签约,但我很绝望。
可在此处找到包含示例的完整文档:https://github.com/rajanadar/VaultSharp
加密和解密工作正常。只有签名是个问题。
加密代码:
public byte[] EncryptData(byte[] data, string keyName)
{
SecretsEngine transitSecretsEngine = new SecretsEngine
{
Type = SecretsEngineType.Transit,
Path = path
};
Client.V1.System.MountSecretBackendAsync(transitSecretsEngine).Wait();
Client.V1.Secrets.Transit.CreateEncryptionKeyAsync(keyName, new CreateKeyRequestOptions()
{
Exportable = true
}, path).Wait();
EncryptRequestOptions encryptOptions = new EncryptRequestOptions
{
Base64EncodedPlainText = Convert.ToBase64String(data),
ConvergentEncryption = true,
};
Secret<EncryptionResponse> encryptionResponse = Client.V1.Secrets.Transit.EncryptAsync(keyName,
encryptOptions, path).Result;
string cipherText = encryptionResponse.Data.CipherText;
return Encoding.Unicode.GetBytes(cipherText);
}
解密代码:
public byte[] DecryptData(string ciphertext, string keyName)
{
DecryptRequestOptions decryptOptions = new DecryptRequestOptions
{
CipherText = ciphertext,
};
Secret<DecryptionResponse> decryptionResponse = Client.V1.Secrets.Transit.DecryptAsync(keyName,
decryptOptions, path).Result;
return Convert.FromBase64String(decryptionResponse.Data.Base64EncodedPlainText);
}
这是我的签名代码试用版:
public byte[] Sign(byte[] plaintextBytes, string keyName)
{
byte[] hash = ComputeHash(plaintextBytes,SHA256.Create());
GCKMS.SignatureOptions options = new GCKMS.SignatureOptions()
{
Digest = Convert.ToBase64String(hash),
};
Secret<GCKMS.SignatureResponse> result = Client.V1.Secrets.GoogleCloudKMS.SignAsync(keyName,
options).Result;
return Encoding.Unicode.GetBytes(result.Data.Signature);
}
错误是:
VaultSharp.Core.VaultApiException: {"errors":["no handler for route 'gcpkms/sign/Manuel'"]}
最后但同样重要的是我的签名验证代码:
public bool ValidateSignature(byte[] plaintextByte, byte[] signature, string keyName)
{
GCKMS.VerificationOptions option = new GCKMS.VerificationOptions
{
Digest = Encoding.Unicode.GetString(ComputeHash(plaintextByte)),
Signature = Encoding.Unicode.GetString(signature)
};
Secret<GCKMS.VerificationResponse> result =
Client.V1.Secrets.GoogleCloudKMS.VerifyAsync(keyName, option).Result;
return result.Data.Valid;
}
我不确定,但这可能是因为我没有使用带路径的 SecretsEngine。我找不到任何适用于 GoogleCloudKms 的 SecretsEngine。
有用信息:
我用 Guid.NewGuid().ToString();
生成路径。
ComputeHash 是一个自写的函数,它使用给定的算法计算哈希值。这
默认算法是 SHA256。
GCMS 是命名空间的简短版本 VaultSharp.V1.SecretsEngines.GoogleCloudKMS
非常欢迎任何想法和建议。
提前致谢!
虽然 Vault 提供了方便的 Transit 签名,C# wrapper you are using does not support it。
Google KMS 确实提供签名,但它的接口更复杂:您必须自己进行哈希并跟踪密钥版本。
我建议你在 API 包装器上玩个把戏:
- 留下你的加解密密码as-is
- 写入 Transit 后端就好像它是 KV 存储版本 1
- 通过sending your payload as the
input
parameter 获得您的签名
在将数据发送到 Vault 之前,您仍然需要对其进行 base64,以避免二进制编码问题。
所以假设:
- 您想签署文本
Whosebug
- 传输 back-end 安装在
transit
下
- 您的签名密钥被命名为
my-key
这应该让你开始:
var value = new Dictionary<string, object> { "input", Convert.ToBase64String(Encoding.UTF8.GetBytes("Whosebug")) } };
var writtenValue = await vaultClient.V1.Secrets.KeyValue.V1.WriteSecretAsync("sign/my-key", value, "transit");