I tried coming up with my own forged signature that could be validated with OpenSSL (which I intended to use to test other libraries). I haven't succeeded, either because in the particular example I came up with OpenSSL does something that catches the invalid signature, or I messed up somewhere (the likelihood of which is far from negligible). Unfortunately, I don't have much more time to play with this. I decided to share the methodology I used with those of you who are interested in case the info is helpful to anyone, or someone can tell me why the signature I produced doesn't get validated by OpenSSL.
I followed the instructions of Hal Finney's excellent post: http://www.mail-archive.com/cryptography@metzdowd.com/msg06537.html I started out by generating 3072 RSA key pair, with public exponent e = 3. openssl genrsa -des3 -3 -out my.key 3072 the resulting key can be found bellow, the passwords is "test" if you ever want to use it. Then I created the corresponding public key certificate: openssl req -new -x509 -days 1001 -key my.key -out my.cer The public key certificate can be found bellow as well. You can import this in Windows key store, for example. I then created a plaintext file, messageAunicode.txt, for which I computed a signature on (a valid signature). The idea was then to forge a signature on an alternate messageBunicode.txt, without using the private key of course. The two files can be found in attachment, they are in Unicode because I wanted to also try this out with a VBscript implementing a signature function using CAPICOM. (you can get a file in Unicode by opening it with a simple text editor that allows you to save as Unicode, such as notepad, and erase any extra bytes (header) with a hex editor such as XVI32). The hashes of these files are openssl dgst -sha1 messageAunicode.txt SHA1(messageAunicode.txt)= eb8302606217ae549fe6ab1345f0b4c804195367 openssl dgst -sha1 messageBunicode.txt SHA1(messageBunicode.txt)= 5d89b46034e0f41a920b2fa964e230ebb2d040b0 Now, create the valid signature over messageAunicode.txt to see what the output looks like: openssl dgst -hex -sha1 -sign my.key messageAunicode.txt Enter pass phrase for my.key: SHA1(messageAunicode.txt)=00d3cda91b578b6df29aeb140272bd9198759f79fa10dc410b 5d10362048ac7abe5df7fe0d94a6646e791c5b95b29f2c6384a570769dc888ed0b7ad510ccd3 c758cebeb648511620490e0fd54162badb1ed05411acc853509b62a4c1b242e1e2f737a1e7e4 340f5a79b05ec3475d7ba6fc73b3302f1258abac1079f11e8dfb9fc09d42716ba4054add460b b12fc1b0b8d5d32db50395374aeb3c215c2bc566328d2f03bf043068c5c9abc649ba1767e97d f32b6aa734594ee22fffe7fb06ea3b77030e79bd6fe7683ab7ffce462abfba5777b3914de466 5b86c1ec203feb6fccb3dadb8ba51fd87a7457c62385418e65d17809c4256e3d27dc2017d7a0 93c8bd193a09168f34d522dd7d3afb95fc61c9f4339091cf25d78bf461b4ea5620eed722ab7d 3eff99cea4a4f546bff6ce338d7763aff20a9b61452da07179590d3316bbce63b06b43d996d7 75d6843f46633ff107a3c866e3b0a8aaaea31f4a2048c9fcb448958287f8e961c9f3393e18fc 9a05460d51a286737aec14a1a7b27a51 Now, let's do some bignumber math. I wanted to look at the value obtained when you verify a signature (RSA encrypt the signature with exponent 3). I use BC, a bignumber calculator I like allot: http://www.gnu.org/software/bc/ A version that can be installed on Windows: http://gnuwin32.sourceforge.net/packages/bc.htm I use a fast modexp function I implemented for BC, available at http://crypto.cs.mcgill.ca/~stiglic/Programming/modgroup.bc You can load it by simply calling bc like this: bc modgroup.bc I did the calculations all in hex, so typed the following in bc obase=16 ibase=16 Now, denote by s the signature given above, e = 3 and m is the modulus in the public key certificate I generated. When pasting the values into BC, the hex digits need to be in capital letters. You can get the value of the modulus by using a ASN.1 viewer, such as ASN.1 Editor or Peter Gutmann's ASN1dump. Here are the BC calculations: s=00D3CDA91B578B6DF29AEB140272BD9198759F79FA10DC410B5D10362048AC7ABE5DF7FE0D 94A6646E791C5B95B29F2C6384A570769DC888ED0B7AD510CCD3C758CEBEB648511620490E0F D54162BADB1ED05411ACC853509B62A4C1B242E1E2F737A1E7E4340F5A79B05EC3475D7BA6FC 7B3302F1258ABAC1079F11E8DFB9FC09D42716BA4054ADD460BB12FC1B0B8D5D32DB50395374 AEB3C215C2BC566328D2F03BF043068C5C9ABC649BA1767E97DF32B6AA734594EE22FFFE7FB0 6EA3B77030E79BD6FE7683AB7FFCE462ABFBA5777B3914DE4665B86C1EC203FEB6FCCB3DADB8 BA51FD87A7457C62385418E65D17809C4256E3D27DC2017D7A093C8BD193A09168F34D522DD7 D3AFB95FC61C9F4339091CF25D78BF461B4EA5620EED722AB7D3EFF99CEA4A4F546BFF6CE338 D7763AFF20A9B61452DA07179590D3316BBCE63B06B43D996D775D6843F46633FF107A3C866E 3B0A8AAAEA31F4A2048C9FCB448958287F8E961C9F3393E18FC9A05460D51A286737AEC14A1A 7B27A51 m=01D851D5148345606F586935D227CD5CF7F04F890AC5024178BA5F4EE85D7796918C3DC7A5 951C985539CB240E28BA4AC3AFBE0F6EB3151A0DBAFD686C234A30D07D590D61A5474491BF0D 68E1AC7F94CDC989C19C2E25B12511A29FFAF5F11E0B994E19C5C3DC298F9E584FFF3C7DBB8F 703A0EAD97167F88C7229BBFA55B449CDE4C91B409D5B9ACF0134CB61352E9CE6CB3D847C7F3 D9AFA74E8E19DD1ED7923270E310A5D91E97EF198694465950715AA066ACB06FAEC0BA64FCCC A155104852EFD41346F75D1ACB8574BBE3C7C8D6D1B501C1163AD2058506DF1B64059A6932C0 672FB9D094364EA4D7FA04442B8E643B74B8746B594866C7CBDAB8FEA954FDEE7C44B9C5D6B9 E19B49082D65B517EA7DBFEF5CA1EEA39AB2283CDB854C8B246F2B8EFE51895349640248A324 8EC65F64A89CA5AB194B444DF676B015AFBCACE13697CEEB5268F5E9AA674A83DD1B0CE4DC83 603CFFB801DB669216FC647CD7A6A84831E421D9676C7AAC44411B2AB3E901A7139B3519B58E BAEEC20B modexp(s, 3, m) 1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFF003021300906052B0E03021A05000414EB8302606217AE549FE6AB134\ 5F0B4C804195367 You can see the 01 FF FF FF .. FF pattern followed by 003021300906052B0E03021A05000414 Which is the ASN.1 header (with 00 in front of it) followed by EB8302606217AE549FE6AB1345F0B4C804195367 Which is the hash of messageAunicode.txt as we calculated above. Now, let's do the calculations in Hal's post, using the above ASN.1 header (which stays the same for all signatures using the above key and the SHA1 algorithm), with the hash of messageBunicode.txt in order to forge a signature over the content of messageBunicode.txt Since we are calculating in hex, here are the equivalences of the exponents which are given in decimal in Hal's post: 288d = 120h 1019d = 3FBh 34d = 22h Now, in bc, using the notations of Hal's post : d=003021300906052B0E03021A050004145D89B46034E0F41A920B2FA964E230EBB2D040B0 n = 2^120 - d n FFCFDECFF6F9FAD4F1FCFDE5FAFFFBEBA2764B9FCB1F0BE56DF4D0569B1DCF144D2F\ BF50 s = 2^3FB - (n*2^22)/3 s 7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAAEAD6EAB6B2B18EBD595822B1555\ AC5D20CF08046814578C2B994E1DBD8413A43C0564000000000 Now let's look at s^3 1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003021300906052B0E03021A05000\ 4145D89B46034E0F41A920B2FA964E230EBB2D040B00000000000000000000000000\ 00000000000000000000000000000000000000000000000000000000000000000000\ 0000000002A9AA11CBB60CB35CB569DDD576C272967D774B02AE385C6EE43238C8C9\ 1477DBD0ED06ECF8BC4B8D3DC4D566FA65939092D09D13E0ED8F8BE5D5CB9E72C47C\ 743B52BBFA7B9697FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA285694CD9347AB7528\ D15F9D0DBF0C82C967D1C7CA3CCF69D2E09519FEAD7B96F1FCCB6D7D78AC9B244C2D\ 85C08FEE0982D080AB2250A546F64BF15B1C540EA5655A36E52756CC57BBB11BBA3B\ 81D72CE1FB7EBFB784027F3087CA7078541278C45764E6F2B1F3E532400000000000\ 00000000000000000 This has the form we are looking for, the 01 FF FF ... FF header that ends with 00, and then we have 03021300906052B0E03021A050004145D89B46034E0F41A920B2FA964E230EBB2D040B0 which is the d we started out with, and the rest is the GARBAGE part. Only one problem, s^3 is larger than m, so if we computed modexp(s, 3, m) the result would be rounded out modulo m and we would loose the above structure. So what I did (and this might be a mistake, but I believe it works because of the explanation I will give), is took s as the signature but cutting out 00 at the end in order to produce s': sp=s/100 sp^3 will start with the same digits as s^3, but will be smaller. Let's look at the modexp calculation modexp(sp, 3, m) 1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003021300906052B0E03021A05000\ 4145D89B46034E0F41A920B2FA964E230EBB2D040B00000000000000000000000000\ 00000000000000000000000000000000000000000000000000000000000000000000\ 0000000002A9AA11CBB60CB35CB569DDD576C272967D774B02AE385C6EE43238C8C9\ 1477DBD0ED06ECF8BC4B8D3DC4D566FA65939092D09D13E0ED8F8BE5D5CB9E72C47C\ 743B52BBFA7B9697FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA285694CD9347AB7528\ D15F9D0DBF0C82C967D1C7CA3CCF69D2E09519FEAD7B96F1FCCB6D7D78AC9B244C2D\ 85C08FEE0982D080AB2250A546F64BF15B1C540EA5655A36E52756CC57BBB11BBA3B\ 81D72CE1FB7EBFB784027F3087CA7078541278C45764E6F2B1F3E532400000000000\ 00000000000 Good! So sp is my tentative forged signature. I saved it to a file in order to try to verify it with OpenSSL. I don't know how to make openssl command line to verify a signature that is represented in hex (it can output a signature in hex, but I can't seem to find how to verify one in this format, seems to only accept binary). I look for a hex2bin converter, which is harder to come by than you would think. Finally, not wanting to code something (to lazy) I used XVI32 hex editor in some unorthodox way to transform the hex signature in binary. The result can be found in attachment. Unfortunately (or fortunately), I can't get OpenSSL to validate this signature. openssl dgst -prverify my.key -sha1 -signature opensslB-fake.sig messageBunicode.txt Enter pass phrase for my.key: Verification Failure (I copied here the verification command that uses the private key, you can of course use the verification command with just the public key, at the moment of writing this I simply couldn't remember how to make it work). If you know what is happening, please tell me. Hope the info is useful to someone! --Anton -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,162F46975BB386BE U+XI4o9mWIb6HzeXMY7XIkuNEpApqSzLbP95TUD74DkCBi4Y7oYxksxqiV+tmmKM BJxLHmyxtSc+LaobSisAgfpTBILtaUezE8yt816ekj53a/A3JtVE70QiotIQJKY1 LZS+RL6bHMPdkGAiICh0CwnLK74/3sgH3TdSsSG70Qhy+H8IX7YPJnJAZnMxr/98 fR8/Nwc9zlcLNuplqqAQTznGHFGO/Z6OjHv8CKAjkK5Mn0HfHn/5xUYpmXuKZW76 fwUmVXonf8hzeYg4n+ZQu+AoQkO05HUeFk52DaYcYaoQ5LGAhIDwF/OSPRz2gQAR YnpN2fGkzv9Fp4OD1G1ZfptiWwdVQBPV2S7n2FzHJ9justn0DYuKHLG+4wVp/s3O t6aLI33EjjB055gft+nwVfyQiFy8un9JwUSHt71vhHV3VhbxOfmxpBy9mGTTt+av iw4Q3Kho6uEy3vwxl9ilmRNGllkBFqPDzcLo4EyWH/J8eD1/w+AXlQnEo7LdD/1X XHzurL3MzFxhoC60B93Tu+EctMFlzJliJ8RC9KP41W91JHXSGDEMN9rIEkveHpRI 8rfqs64THDw++/p4o+e1fOxRMy2FzbgDsoKAT330c2A2t6YLX1P5T3kbHM6Su3RW OibdQLf5D/N2OlTkDUc2+wLfLlfZJ2RqNk6UC5w8oqv2G1uNp9vD08d23L8Jjid9 Ub2er4FqXcN/du1zeQawka3CrwZNV1KxkV83SShKvEGfC4cGWtAzzA7QenVLLUen AXRDBA2WevQR4M36XsoYJM79LyZMj5V6hFzUSHnPqNj/JSbQgGAV29D3J9mFWrPf iZuR/6TEm3VgAuTK168UHQEC/Tp/57dC6OSc5jmthWu3Fx1maaQh9hfXRE8CcOol ckE9hTLPYq83ZZ45qRKF+uRoaHnQFy3KP/nD1vuexTeTVaZCZOv/SZUYfNy0ZPoh lTSOWwcrtdAH4e11bQniQ6Bq9YFwZo+SLJIGLaP5HEnHqvpflItu0zNAXACh0B9K ZDZ31jhUn0qRHERyL+kDsMvzSreL0wRKUc9xJpZF8X0GDiVHznQTUbEJF6gEKntC 5qZw6c1Ga4/jQe7AvuyLpAItHl0g2uOuHLLLV7DUsVDWIIpZ4aZVb9TpkjMgHZq4 Umk4V8gTnJvtwBxKbb05M56myW1D5QH2TSoC2kW2BTlq7GDmJ2141vupzr1W3V53 ng7zrDL5Qay6bejSHcqsIC1YQ7gIu9XCZqiTPq0RowvXsQEhAR3bi3+SXbyb3rt8 SFCbcTZObtnCTZ4iJOgqcjWSG+etpvgJwKBH214at2DgeX2eZVkklbkdWvDvrqoT Ir5jb6gkqWUVARSrwCg4pUzPe6mOp1CWUH+eifz36haeLZN8mfrpX6HbSdN1bhlX ocgKpbGqam8jtdKT2Dd8YaEwM4D4GxZzmoLVhOVlawyItFnwEfYM1/V04Qwp7jFY 7l9Ld6DKffV157DKlHqFROVh1coWqC9UIudPTlgE7oDmtQT0O2tozNxqNeVkzmLH bNSDZKLyBCS+xHp5MaEOVrzPtqImmpbqxl40qvvp2JdpNb8YGzRu1OSiDCUDL0ho SbombAc3YuBYolinOqNzu3EI90ML2/hCQ+Vc0+/4ScP/T0kKFyRGbaHr2F6hWKde /xI/NPyZ2HqMvxvkJDkBK0EfzqsSpYo5gV9GfPOmSBQ4Qb1K0Q620kcZFjf/soNW hRNdjiMo2jT6ocdtJ90KnLGjoqQEFEoj+qLgrEagKY5X9tn0GfdKJLBCJYGbVlRH aKjp68ajR3G/NaEEjmZwGyx5f7NeHLhNpjnJwRl8RgS7R99rFwLPCKLNLurWsgUb Gd6v0RtyC6qTZJi4I1vvc3oRZNdDhLJI2J7SJPeZbaH+v1PHlq3s4ubLyxmTxcVW cvdlztmuga9cRY5MyCm1eKHbEx8bxzf5UKsCKfXoPOIlOmkpVTcXlfDjioDgVaQy xMGeyv/k8Zk6F3EzfBuoqsl9siQ7+RG/5CC9Vfmh/gFqq/uE+ZjEGzBGTwRyrUpF xVLWQRstEJFeQ0BeMINVv1NhokdH8EY6/y4cPHnVlT3f1mfFpNm+LpiMM5bs0Yov jpD73x+X0kHBMw418aLkn6y4byfieU3ntKY8PwtaJKD3IK0Yp6TTt5LAaOdb0Mez iHTJ6LMVk0EZCHtIN1fZ6MR9mKhrZRBVPO2c31eW8IxD+ckv8Gni2SB6SSlZL6aV mFIuTDiXwTNrQTPY21M8fGv2Xbj+OT8RElpm4vtDYMEbelupUAtVxnbf9RcOaBRX 3BlWtFuV0KsNymLUFHQ9gbwjImY8eGyaA2Dys0iFIC0= -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIFaTCCA9KgAwIBAgIJAObO4xl/ruKUMA0GCSqGSIb3DQEBBQUAMIGAMQswCQYD VQQGEwJDQTELMAkGA1UECBMCUUMxETAPBgNVBAcTCE1vbnRyZWFsMRYwFAYDVQQK Ew1JbnN0YW50IExvZ2ljMQwwCgYDVQQLFANSJkQxDzANBgNVBAMTBk1yIEZvbzEa MBgGCSqGSIb3DQEJARYLZm9vQGZvby5jb20wHhcNMDYwOTE4MjEzNTU2WhcNMDkw NjE1MjEzNTU2WjCBgDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAlFDMREwDwYDVQQH EwhNb250cmVhbDEWMBQGA1UEChMNSW5zdGFudCBMb2dpYzEMMAoGA1UECxQDUiZE MQ8wDQYDVQQDEwZNciBGb28xGjAYBgkqhkiG9w0BCQEWC2Zvb0Bmb28uY29tMIIB njANBgkqhkiG9w0BAQEFAAOCAYsAMIIBhgKCAX8B2FHVFINFYG9YaTXSJ81c9/BP iQrFAkF4ul9O6F13lpGMPcellRyYVTnLJA4oukrDr74PbrMVGg26/WhsI0ow0H1Z DWGlR0SRvw1o4ax/lM3JicGcLiWxJRGin/r18R4LmU4ZxcPcKY+eWE//PH27j3A6 Dq2XFn+IxyKbv6VbRJzeTJG0CdW5rPATTLYTUunObLPYR8fz2a+nTo4Z3R7XkjJw 4xCl2R6X7xmGlEZZUHFaoGassG+uwLpk/MyhVRBIUu/UE0b3XRrLhXS748fI1tG1 AcEWOtIFhQbfG2QFmmkywGcvudCUNk6k1/oERCuOZDt0uHRrWUhmx8vauP6pVP3u fES5xda54ZtJCC1ltRfqfb/vXKHuo5qyKDzbhUyLJG8rjv5RiVNJZAJIoySOxl9k qJylqxlLRE32drAVr7ys4TaXzutSaPXpqmdKg90bDOTcg2A8/7gB22aSFvxkfNem qEgx5CHZZ2x6rERBGyqz6QGnE5s1GbWOuu7CCwIBA6OB6DCB5TAdBgNVHQ4EFgQU 5nm4J2leKJRiQq8Ollw+FIA448gwgbUGA1UdIwSBrTCBqoAU5nm4J2leKJRiQq8O llw+FIA448ihgYakgYMwgYAxCzAJBgNVBAYTAkNBMQswCQYDVQQIEwJRQzERMA8G A1UEBxMITW9udHJlYWwxFjAUBgNVBAoTDUluc3RhbnQgTG9naWMxDDAKBgNVBAsU A1ImRDEPMA0GA1UEAxMGTXIgRm9vMRowGAYJKoZIhvcNAQkBFgtmb29AZm9vLmNv bYIJAObO4xl/ruKUMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggGAAAD7 SqzMT8qM9VOZ7uQdBCdKgapFgrwTPPHt0c7zKHwQm+OYctf64WEREeltedr0LsUx q3/+ahPqW167NUiZCYfdAhliUap9Ma0/rpmlxBKq5NvwzmB/xNZOknrUlK7ouOxR 0OOK9GtuRgQKYF9IQ8RBwT4aU4KEbu9w+hZYunf01vrtRK3TO8yg5b7LiEiSvDIv g+JXCLgubjXCq64uDUJW2FdRWnE+MiFC6Nadus6xfWnKjrAcDQjQuBgfJnAmlZ/r lJ+p1Qzy9UuHVmECvDJNWXn8+s/p70mnBx+ErtwFwmHg6QtY6WXm5MKDr3QBW7oT zRnVDMvHtyztvln5jukMFf58O546K7jVzNgGQgDcqf35YAAhzBfGeG//X0eYyYT8 6+x9V7Cvi56G13mh3o4MmFU7U4SOxOuRySCg79G1P0dC6YOQRgOEvWrUlcQG4CTF Q/NGr9iqxj0bvfYswwn2HyEd63bOZYD/w8tOAK2Zfqo9hzk22U1F6FC84aEP -----END CERTIFICATE-----
P l e a s e t r a n s f e r $ 2 5 . 0 0 U S f r o m m y a c c o u n t .
P l e a s e t r a n s f e r $ 2 . 5 0 0 , 0 0 0 . 0 0 U S f r o m m y a c c o u n t , a n d r u s h !
opensslB-fake.sig
Description: Binary data