Prepare Test data
echo -n "hello world" > msg.txt
Asymmetric keys always operate with short-length input:
Such as:
- digest
- shared symmetric key
corresponding to TWO working mode:
- sign & verify
- encrypt & decrypt
So, do NOT sign with a large input, which may violate with KEY_SIZE.
Prepare digest of a message
openssl sha256 -binary -out hash.dat msg.txt
# hd hash.dat
00000000 b9 4d 27 b9 93 4d 3e 08 a5 2e 52 d7 da 7d ab fa |.M'..M>...R..}..|
00000010 c4 84 ef e3 7a 53 80 ee 90 88 f7 ac e2 ef cd e9 |....zS..........|
Prepare RSA Key pairs
openssl genrsa -out cakey.pem 2048
openssl rsa -in cakey.pem -pubout -out capub.pem
pkeyutl
sign
openssl pkeyutl -sign -in hash.dat -inkey cakey.pem -out sig
#hd sig
00000000 a2 78 7a f4 4f 66 ba 14 d2 55 9a 32 59 5e c1 f7 |.xz.Of...U.2Y^..|
00000010 2d eb 33 f8 5b ee b3 da 62 4b d6 a7 17 d6 11 df |-.3.[...bK......|
00000020 8b fe 01 76 37 46 7e 34 6e f5 9a 4f a4 d6 82 d1 |...v7F~4n..O....|
00000030 49 d4 78 a3 25 7a 85 d6 de fc 4a 8e fe 17 4a 84 |I.x.%z....J...J.|
00000040 32 0c b5 e5 25 3d 93 37 f6 a6 81 84 8f fb 79 34 |2...%=.7......y4|
00000050 c6 f3 bd 75 26 e1 58 85 ec 72 3d 96 18 31 4c d9 |...u&.X..r=..1L.|
00000060 85 24 9b 69 99 70 a8 39 d2 93 c0 9b 0b 81 e0 58 |.$.i.p.9.......X|
00000070 75 08 79 a8 2b 2a 4c 04 aa 35 e4 89 30 4a 1b f2 |u.y.+*L..5..0J..|
00000080 b6 d0 62 7e 03 58 3b 63 68 e1 87 14 66 84 bc 67 |..b~.X;ch...f..g|
00000090 2e b3 05 f9 c0 a5 43 61 47 f8 54 ee f5 7b 15 62 |......CaG.T..{.b|
000000a0 f6 72 86 57 7d aa 95 0e a3 95 c3 85 6f 30 69 6b |.r.W}.......o0ik|
000000b0 81 5e ae 81 00 3f a3 b8 4a aa 73 e3 e3 15 13 16 |.^...?..J.s.....|
000000c0 0a d5 05 2b a0 68 b7 e4 4e a2 6d c1 c5 ec 5f ee |...+.h..N.m..._.|
000000d0 42 6a 0d e5 51 2f b0 3a ef 21 36 44 99 35 63 53 |Bj..Q/.:.!6D.5cS|
000000e0 2a 3b f5 cc ae f0 0f eb 73 c3 2f 74 43 b0 57 cd |*;......s./tC.W.|
000000f0 cd 9d 68 a3 91 82 fc 33 94 a6 91 27 1f 34 7b a7 |..h....3...'.4{.|
verify
# openssl pkeyutl -verify -in hash.dat -sigfile sig -inkey cakey.pem
Signature Verified Successfully
# openssl pkeyutl -verify -in hash.dat -sigfile sig -pubin -inkey capub.pem
Signature Verified Successfully
but oops, if you type like this:
# openssl pkeyutl -verify -in hash.dat -sigfile sig -inkey capub.pem -pubin
sign with pkeyopt
# openssl pkeyutl -in hash.dat -inkey cakey.pem -pkeyopt digest:sha256 -out sig2
# hd sig2
00000000 b3 e6 3f 33 ab 27 00 f6 66 42 4a c6 78 87 ca bc |..?3.'..fBJ.x...|
00000010 39 d5 be 81 3a 18 1f c9 3a 5b 9b 8a af 40 6a 98 |9...:...:[...@j.|
00000020 29 3e 81 85 ca 63 d6 1b a9 31 96 b0 e2 f1 bf c8 |)>...c...1......|
00000030 67 e8 67 8d 09 fd d8 10 fb 65 4f a2 43 1e ca 02 |g.g......eO.C...|
00000040 1c 90 43 72 90 d3 6c 18 d1 eb 3f 53 f6 8b 1c 33 |..Cr..l...?S...3|
00000050 eb b4 8e 53 18 05 5a 28 83 c8 44 cc f4 f6 d8 dc |...S..Z(..D.....|
00000060 9a a5 6c c7 9d d0 b7 13 a3 e6 7d e9 de 86 2b 4e |..l.......}...+N|
00000070 5e 88 ef 5a 3f 4a 7e 25 dd 39 7d 97 0c 8c c1 8f |^..Z?J~%.9}.....|
00000080 89 56 a1 be c9 8a 4e d9 2c 74 67 64 18 54 18 52 |.V....N.,tgd.T.R|
00000090 6d b2 7a f5 a7 b0 8a ec 53 a5 3d ba a2 6d d4 92 |m.z.....S.=..m..|
000000a0 c9 d8 9d 85 dd 64 fc f8 e7 51 24 71 29 04 b0 d6 |.....d...Q$q)...|
000000b0 bc 96 c7 e9 00 6f 4e 06 99 bf 16 ad 7a 87 10 af |.....oN.....z...|
000000c0 c7 84 eb 6f 00 4d e6 af 6d 6b 3a 23 9d d3 5e 69 |...o.M..mk:#..^i|
000000d0 7d 40 cd 31 5c c3 ee ba 69 3c 69 92 55 d5 46 b2 |}@.1\...i<i.U.F.|
000000e0 87 e6 a5 37 7c 88 bf 97 39 28 d6 b0 cc c7 18 47 |...7|...9(.....G|
000000f0 39 30 2b 46 29 47 8e b8 8f eb 4f 5c d0 9b 71 78 |90+F)G....O\..qx|
The output sig2 is NOT same as previous sig, because -pkeyopt will pack some digest algorithm information into signature, such as, sha256.
so, when verify, -pkeyopt is required:
# openssl pkeyutl -verify -in hash.dat -sigfile sig2 -pubin -inkey capub.pem -pkeyopt digest:sha256
Signature Verified Successfully
# openssl pkeyutl -verify -in hash.dat -sigfile sig2 -pubin -inkey capub.pem
Signature Verification Failure
To view original hash, use -verifyrecover option:
hash data begins at offset 0x13 (0xb9, 0x4d…)
# openssl pkeyutl -verifyrecover -in sig2 -pubin -inkey capub.pem | hd
00000000 30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 |010...`.H.e.....|
00000010 00 04 20 b9 4d 27 b9 93 4d 3e 08 a5 2e 52 d7 da |.. .M'..M>...R..|
00000020 7d ab fa c4 84 ef e3 7a 53 80 ee 90 88 f7 ac e2 |}......zS.......|
00000030 ef cd e9 |...|
more verbose output of recovered data, with -asn1parse option:
# openssl rsautl -in sig2 -verify -asn1parse -inkey capub.pem -pubin
0:d=0 hl=2 l= 49 cons: SEQUENCE
2:d=1 hl=2 l= 13 cons: SEQUENCE
4:d=2 hl=2 l= 9 prim: OBJECT :sha256
15:d=2 hl=2 l= 0 prim: NULL
17:d=1 hl=2 l= 32 prim: OCTET STRING
0000 - b9 4d 27 b9 93 4d 3e 08-a5 2e 52 d7 da 7d ab fa .M'..M>...R..}..
0010 - c4 84 ef e3 7a 53 80 ee-90 88 f7 ac e2 ef cd e9 ....zS..........
or
# openssl pkeyutl -verifyrecover -in sig2 -asn1parse -pubin -inkey capub.pem
0:d=0 hl=2 l= 49 cons: SEQUENCE
2:d=1 hl=2 l= 13 cons: SEQUENCE
4:d=2 hl=2 l= 9 prim: OBJECT :sha256
15:d=2 hl=2 l= 0 prim: NULL
17:d=1 hl=2 l= 32 prim: OCTET STRING
0000 - b9 4d 27 b9 93 4d 3e 08-a5 2e 52 d7 da 7d ab fa .M'..M>...R..}..
0010 - c4 84 ef e3 7a 53 80 ee-90 88 f7 ac e2 ef cd e9 ....zS..........
or pipe out the recovered data to asn1parse utility:
# openssl pkeyutl -verifyrecover -in sig2 -pubin -inkey capub.pem | openssl asn1parse -inform der -i
0:d=0 hl=2 l= 49 cons: SEQUENCE
2:d=1 hl=2 l= 13 cons: SEQUENCE
4:d=2 hl=2 l= 9 prim: OBJECT :sha256
15:d=2 hl=2 l= 0 prim: NULL
17:d=1 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:B94D27B9934D3E08A52E52D7DA7DABFAC484EFE37A5380EE9088F7ACE2EFCDE9
# openssl pkeyutl -verifyrecover -in sig2 -pubin -inkey capub.pem | openssl asn1parse -inform der -i -strparse 2
0:d=0 hl=2 l= 13 cons: SEQUENCE
2:d=1 hl=2 l= 9 prim: OBJECT :sha256
13:d=1 hl=2 l= 0 prim: NULL
Analyze output sig if no -pkeyopt present
# openssl pkeyutl -verifyrecover -in sig -pubin -inkey capub.pem | hd
00000000 b9 4d 27 b9 93 4d 3e 08 a5 2e 52 d7 da 7d ab fa |.M'..M>...R..}..|
00000010 c4 84 ef e3 7a 53 80 ee 90 88 f7 ac e2 ef cd e9 |....zS..........|
if no -pkeyopt , the input hash is NOT packed with meta informations(e.g. digest algorithm, etc.), that is, the NAKED hash is used as the input of sign process. So the recovered signature is only have the hash itself, and which can not be analyzed by asn1parse utlity.
Notice: in x509 storage, the signature is calculated with ASN1 Wrapped hash of the tbsCeritifcate. That is, the tbsCertificate’s hash is wrapped with algorithm information in ASN1, before calculating the whole certificate’s signature.
rsautl
- Show original hash
# hd hash.dat
00000000 b9 4d 27 b9 93 4d 3e 08 a5 2e 52 d7 da 7d ab fa |.M'..M>...R..}..|
00000010 c4 84 ef e3 7a 53 80 ee 90 88 f7 ac e2 ef cd e9 |....zS..........|
00000020
- Sign input hash with private key
# openssl rsautl -sign -in hash.dat -inkey cakey.pem -out hash.sig && hd hash.sig
00000000 a2 78 7a f4 4f 66 ba 14 d2 55 9a 32 59 5e c1 f7 |.xz.Of...U.2Y^..|
00000010 2d eb 33 f8 5b ee b3 da 62 4b d6 a7 17 d6 11 df |-.3.[...bK......|
00000020 8b fe 01 76 37 46 7e 34 6e f5 9a 4f a4 d6 82 d1 |...v7F~4n..O....|
00000030 49 d4 78 a3 25 7a 85 d6 de fc 4a 8e fe 17 4a 84 |I.x.%z....J...J.|
00000040 32 0c b5 e5 25 3d 93 37 f6 a6 81 84 8f fb 79 34 |2...%=.7......y4|
00000050 c6 f3 bd 75 26 e1 58 85 ec 72 3d 96 18 31 4c d9 |...u&.X..r=..1L.|
00000060 85 24 9b 69 99 70 a8 39 d2 93 c0 9b 0b 81 e0 58 |.$.i.p.9.......X|
00000070 75 08 79 a8 2b 2a 4c 04 aa 35 e4 89 30 4a 1b f2 |u.y.+*L..5..0J..|
00000080 b6 d0 62 7e 03 58 3b 63 68 e1 87 14 66 84 bc 67 |..b~.X;ch...f..g|
00000090 2e b3 05 f9 c0 a5 43 61 47 f8 54 ee f5 7b 15 62 |......CaG.T..{.b|
000000a0 f6 72 86 57 7d aa 95 0e a3 95 c3 85 6f 30 69 6b |.r.W}.......o0ik|
000000b0 81 5e ae 81 00 3f a3 b8 4a aa 73 e3 e3 15 13 16 |.^...?..J.s.....|
000000c0 0a d5 05 2b a0 68 b7 e4 4e a2 6d c1 c5 ec 5f ee |...+.h..N.m..._.|
000000d0 42 6a 0d e5 51 2f b0 3a ef 21 36 44 99 35 63 53 |Bj..Q/.:.!6D.5cS|
000000e0 2a 3b f5 cc ae f0 0f eb 73 c3 2f 74 43 b0 57 cd |*;......s./tC.W.|
000000f0 cd 9d 68 a3 91 82 fc 33 94 a6 91 27 1f 34 7b a7 |..h....3...'.4{.|
00000100
- Verify signature with public key and hexump it out
# openssl rsautl -verify -in hash.sig -inkey capub.pem -pubin -hexdump
0000 - b9 4d 27 b9 93 4d 3e 08-a5 2e 52 d7 da 7d ab fa .M'..M>...R..}..
0010 - c4 84 ef e3 7a 53 80 ee-90 88 f7 ac e2 ef cd e9 ....zS..........
dgst
- Sign a file for integrity
# openssl dgst -sha256 -sign cakey.pem -out 1.tgz.sig 1.tgz
- Verify a signature of a file
# openssl dgst -sha256 -verify capub.pem -signature 1.tgz.sig 1.tgz
Verified OK