ruby - 离线验证签名数据保险库
问题描述
我正在向客户发送一个 public_key 和一个有效负载以及一个签名。
我正在尝试使用 public_key 和有效负载验证客户端上的签名,但我找不到验证数据的方法。每次无论我在做什么,我都会收到错误的回应。
我正在使用保险库对有效负载进行签名
def sign(box_identifier, data) do
Vaultex.Client.write("transit/sign/#{box_identifier}",
%{
input: data,
hash_algorithm: "sha2-256"
},
@authentication_strategy,
{@token})
end
Vault.Transit.sign("coucou", Base.encode64("test"))
_____________________________________________________________
digest = OpenSSL::Digest::SHA256.new
key = OpenSSL::PKey::RSA.new File.read 'key.pem'
key.public_key.verify digest, signature, "test"
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzj0qLxEc0Qu9g9nxdMRe
jBaUD0+GuQITiAPEDOrjScJTznJrR9hXqO14BqepuEmcz4irv4hEkBEBfqZ1XnP9
2fc9zG4A20lepqDRwPhkEdI4D71KRPSxv/a+O2HrAhTYH17NbsYDtpkFCdepC6FC
01aso679d3kAZiZ+GD2OLDWifreBVPE2aXacJYXZZ4kTkchsevY3PnAcOG4LmM6b
kUoF1qfP6tJ/VItJXyqSC2PI9Io28zFhwOf6cPLEQCBCTNCNwHunqHW8olcE/Xfn
b2toym0/UvW3kH/P4h+TE1ZoCV5FWwcx9hcAy1TC0zm4D5Xwt0/4Pgj1GiXFGOY4
WKGyuDK8gs7QsSDqu+B5p0xiDg7226bpplVxR/P87CohYTtYZj/lO03G2ZEj3pCr
/juxThdzTgO5xUcPV5GFbPjlK1TIIb5XVZZzW6+sviB6cYZ5T/Xp9dtbR8G9Zt9n
gLlaKU7U/DDQxRv2uiCZy5U/DUpfxY56r4Y73Ir2YgmZY1PKLC2a5/w3wScVZILN
fnxnVYOzSPPaKxAJWbZsZjxXJS0veE8RgGFHgWfe8+qPCEnx81Jf2NzupQHO1KIk
UnlYGcPESk/90psDNsmISSdtF2D6j4k28k0ncViTu2eMKBX81W8TgTeHtQa3zR0S
upN2o25b3Wi2oQU14kTdOCcCAwEAAQ==
-----END PUBLIC KEY-----
当它由保险库签名时,我什至能够离线验证签名吗?
解决方案
是的,可以离线验证签名。我的回答会提到一些 Ruby 的细节,因为直到我开始进行更多研究之后,我才注意到这是 Elixir。
默认情况下,使用 RSA 密钥进行签名时,Vault 使用PSS
签名算法。上的verify
方法OpenSSL::PKey::PKey
是期待的PKCS #1 v1.5
。以下是有关两者优缺点的一些有用信息。
除了这种算法差异之外,您还需要vault:v1:
从 Vault 返回的签名中去除 。
这是一些用于签名然后验证签名的示例 Ruby 代码:
transit_key = "test_key"
message = "test"
# Returns something like:
# vault:v1:B3reNpf8e/WyAYzBzyWz3oSUM...
signature = Vault.logical.write(
"transit/sign/#{transit_key}/sha2-256",
input: Base64.encode64(message),
signature_algorithm: "pkcs1v15"
).data[:signature]
signature = signature.split(":")[2]
# Gives us the PEM encoded public key
# -----BEGIN PUBLIC KEY-----
# ...
public_key = Vault.logical.read("transit/keys/#{transit_key}").data[:keys][:"1"][:public_key]
public_key = OpenSSL::PKey::RSA.new(public_key)
digest = OpenSSL::Digest::SHA256.new
puts public_key.verify(digest, Base64.decode64(signature), message) # returns true
puts public_key.verify(digest, Base64.decode64(signature), message + "modified") # returns false
看起来从 Ruby 2.5 开始,类verify_pss
上有一个新方法OpenSSL::PKey::RSA
。
signature = Vault.logical.write(
"transit/sign/#{transit_key}/sha2-256",
input: Base64.encode64(message),
signature_algorithm: "pss"
).data[:signature].split(":")[2]
puts public_key.verify_pss(digest, Base64.decode64(signature), message, salt_length: :auto, mgf1_hash: "SHA256") # returns true
puts public_key.verify_pss(digest, Base64.decode64(signature), message + "modified", salt_length: :auto, mgf1_hash: "SHA256") # returns false
推荐阅读
- c++ - 为什么 int x{ y = 5 } 可能?
- html - 盒子定位包装
- php - DataFixtures phpunit symfony 类型的预期值改为“整数”
- reactjs - 常规函数中的 Redux 钩子(钩子规则)
- sql - SQL:聚合总和和过滤的聚合总和
- api - Laravel 6 单元测试响应 401
- java - 碎片内存泄漏
- angularjs - SpringBoot AngularJS webSocket 集成
- sql - 如何从 SQL SERVER 中的日期时间戳的时间部分创建一天的四分之一
- angular - 如果存在显示警报,如何编写条件,否则添加到列表