我发现当我调用OpenSSL::PKCS7#verify时,如果要验证的数据包含换行符,则verify返回FALSE:

require 'openssl'

def test(data)
  store = OpenSSL::X509::Store.new
  signed = OpenSSL::PKCS7.sign(@cert, @key, data).to_der
  pkcs7 = OpenSSL::PKCS7.new(signed)
  valid = pkcs7.verify(pkcs7.certificates, store, data, OpenSSL::PKCS7::NOVERIFY)
end

@key = OpenSSL::PKey::RSA.new 2048
@cert = OpenSSL::X509::Certificate.new
@cert.serial = 0
@cert.public_key = @key.public_key
@cert.not_before = Time.now
@cert.not_after = Time.now + 2**12
@cert.sign @key, OpenSSL::Digest.new('SHA256')

test("foo")   # => true
test("foo\n") # => false

(我甚至在函数调用中使用了NOVERIFY标志!)

为什么换行符的存在会改变行为?无论我将换行符放在数据字符串中的什么位置,它都会产生这种效果.如果输入字符串包含换行符,我如何验证签名?

This is Ruby 2.6.8p205.

推荐答案

After a lot of head scratching this seems to be expected behavior.
It's converting LF to CRLF before signing:

test("foo")     # => true
test("foo\n")   # => false
test("foo\r\n") # => true

要解决此问题,您需要使用BINARY标志:

signed = OpenSSL::PKCS7.sign(@cert, @key, data, nil, OpenSSL::PKCS7::BINARY).to_der

现在:

test("foo")     # => true
test("foo\n")   # => true
test("foo\r\n") # => true

此信息的来源:

Normally the supplied content is translated into MIME canonical format (as required by the S/MIME specifications). If PKCS7_BINARY is set no translation occurs.如果提供的数据为二进制格式,则应使用此选项,否则转换会损坏该数据.

[1] https://www.openssl.org/docs/man3.1/man3/PKCS7_sign.html
[2] https://github.com/openssl/openssl/issues/9336
[3] https://opensource.apple.com/source/ruby/ruby-75/ruby/test/openssl/test_pkcs7.rb

Ruby相关问答推荐

在Glade创建的UI中以编程方式填充GtkTreeView

如何保证散列中的对象不完全相同

如何判断一个对象在 Ruby 中是否可迭代?

Ruby 中有内置的二进制搜索吗?

Rspec: expectvsexpect什么区别?

在Ruby中将关键字与常规参数混合?

全新安装 RVM 和 Ruby 2.1.1 - dyld 库/路径错误

在 Ruby 中创建数字、字符串、数组或哈希的 md5 哈希

是否有等效于 `Array::sample` 的哈希值?

如何将 STDOUT 捕获到字符串?

需要必要的库和/或头文件时如何安装 ruby​​-debug

Ruby中的常量或类变量?

如何使用 Ruby 2.3 中引入的 Array#dig 和 Hash#dig?

在 Rails 中,如何向 String 类添加新方法?

为什么 Ruby 没有真正的 StringBuffer 或 StringIO?

如何转换 Ruby 哈希,使其所有键都是符号?

纯 Ruby 并发哈希

如何使用 link_to Ruby on rails 添加确认消息

在 Ruby 中创建二维数组和访问子数组

如何在 Ruby 中实现回调?