PKCS#7 Signing: How to get repeatable output for signing the same data

Michal Suchánek msuchanek at suse.de
Mon Oct 17 09:10:14 UTC 2022


On Mon, Oct 17, 2022 at 10:28:45AM +0200, Tim Meusel wrote:
> Hi!
> I maintain a Ruby script that does PKCS#7 signing and afterwards some
> enryption with AES-128-CFB. A trimmed down version:
> 
> certpath = '/tmp/cert.pem'
> keypath = '/tmp/key/pem'
> data = 'teststring'
> key  = OpenSSL::PKey::RSA.new(File.read(keypath), '1234')
> cert = OpenSSL::X509::Certificate.new(File.read(certpath))
> signed = OpenSSL::PKCS7::sign(cert, key, data, [], OpenSSL::PKCS7::BINARY)
> cipher = OpenSSL::Cipher::new("AES-128-CFB")
> iv_len = cipher.iv_len
> key_len = cipher.key_len
> fqdn_rand = Digest::SHA256.hexdigest([destination,data.length].join(':'))
> iv_seed, key_seed = fqdn_rand.partition(/.{32}/)[1,2]
> iv = iv_seed.unpack('a2'*key_len).map{|x| x.hex}.pack('c'*key_len)
> key = key_seed.unpack('a2'*key_len).map{|x| x.hex}.pack('c'*key_len)
> cipher.encrypt
> cipher.iv=(iv)
> cipher.key=(key)
> OpenSSL::PKCS7::encrypt([target], signed.to_der, cipher,
> OpenSSL::PKCS7::BINARY).to_s
> 
> I pulled the AES encryption into a testscript and that's indeed repeatable
> (script at the end of the email). I did some tests and noticed that the
> initial signing doesn't produce repeatable output:
> 
> signed = OpenSSL::PKCS7::sign(cert, key, data, [], OpenSSL::PKCS7::BINARY)
> 
> I did some googling and that told me the signing date/timestamp is part of
> the output, which would explain why it doesn't produce the same output when
> I run it twice. Now to my actual questions:
> * Is the different output caused by a changing signing time and/or something
> else?
> * Do you know if I can pass the signingtime to manipulate it?
> 
> I know that this isn't a Ruby mailinglist, but the ruby-openssl bindings and
> the documentation are generated from the C code and were not very helpful
> (for people not knowing C/not knowing a lot about OpenSSL/PKCS#7). Maybe
> you've some thoughts.
> 
> Why am I doing this?
> 
> Roughly explained, the script is executed every 30 minutes for a lot of
> content, then the previous PKCS#7 output is pulled from a database,
> compared, and if the new script output is different, the DB is updated. This
> is stupid in many ways, but I cannot change that short-term. As a workarond,
> we would like to update the script to produce repeatable output. I know that
> this weakens the security, but we need to reduce the database load from the
> many reoccurring updates.

Hello,
this is code that creates a PKCS#7 signature from a raw RSA signature
without using openssl (because openssl cannot do that) -> you can put
any data you want in it. YMMV

https://github.com/openSUSE/pesign-obs-integration/blob/master/kernel-sign-file#L457

HTH

Michal


More information about the openssl-users mailing list