[prev in list] [next in list] [prev in thread] [next in thread]
List: bouncycastle-crypto-dev
Subject: Re: [dev-crypto] PROBLEM WITH SHA256WithRSAEncryption
From: David Hook <dgh () lockboxlabs ! com>
Date: 2010-08-04 2:13:17
Message-ID: 1280887997.2170.24.camel () konkolo
[Download RAW message or body]
The solution below isn't correct - there was an attack based on
processing signatures like this published some time ago.
If you can send me a Hex dump of sig (as in the result after the cipher
is called) I should be able to tell you what is wrong.
Regards,
David
On Tue, 2010-08-03 at 18:42 +0200, A.Ventura@ads.it wrote:
> Hi,
> I'm using bcprov-jdk15-145.jar to verify a p7m file generated with
> SHA256WithRSA algorithm (in Italy, the SHA256WithRSA algorithm will be
> soon mandatory, instead of SHA1WithRSA, in order to be compliant to a
> new law). I generated this file using a valid smartcard for signing.
> So, I need to be able to verify these kind of files, and trying to do
> this I encountered a problem using SHA256WithRSAEncryption: the verify
> method of SignerInformation.java return false.
>
> I noticed that debugging engineVerify method of
> JDKDigestSignature.java, the "sig" and "hash" local variables have
> identical values before calling derEncode method, but after
> derEncode(hash) call these two values are no longer identical, and
> this will fail the verification:
>
> ....
> byte[] hash = new byte[digest.getDigestSize()];
>
> digest.doFinal(hash, 0);
>
> byte[] sig;
> byte[] expected;
>
> try
> {
> sig = cipher.processBlock(sigBytes, 0, sigBytes.length);
>
> expected = derEncode(hash);
> }
> catch (Exception e)
> {
> return false;
> }
> ....
>
> this code, however works fine with SHA1WithRSA generated pkcs7 files
> (with the same smartcard for signing).
> Then I think there is a bug exactly calling derEncode method, when you
> are using SHA256WithRSAEncryption, do you agree?
>
> I've modified, in my local workspace, the JDKDigestSignature.java in
> this manner:
>
> protected boolean engineVerify(
> byte[] sigBytes)
> throws SignatureException
> {
> byte[] hash = new byte[digest.getDigestSize()];
>
> digest.doFinal(hash, 0);
>
> byte[] sig;
> byte[] expected;
>
> try
> {
> sig = cipher.processBlock(sigBytes, 0, sigBytes.length);
>
> expected = getExpected(hash); //MY NEW CODE
> }
> catch (Exception e)
> {
> return false;
> }
>
> if (sig.length == expected.length)
> {
> for (int i = 0; i < sig.length; i++)
> {
> if (sig[i] != expected[i])
> {
> return false;
> }
> }
> }
> else if (sig.length == expected.length - 2) // NULL left out
> {
> int sigOffset = sig.length - hash.length - 2;
> int expectedOffset = expected.length - hash.length - 2;
>
> expected[1] -= 2; // adjust lengths
> expected[3] -= 2;
>
> for (int i = 0; i < hash.length; i++)
> {
> if (sig[sigOffset + i] != expected[expectedOffset +
> i]) // check hash
> {
> return false;
> }
> }
>
> for (int i = 0; i < sigOffset; i++)
> {
> if (sig[i] != expected[i]) // check header less NULL
> {
> return false;
> }
> }
> }
> else
> {
> return false;
> }
>
> return true;
> }
>
>
> //MY NEW CODE
> protected byte[] getExpected(byte[] hash) throws IOException {
> byte[] expected;
> expected = derEncode(hash);
> return expected;
> }
>
> static public class SHA256WithRSAEncryption
> extends JDKDigestSignature
> {
> public SHA256WithRSAEncryption()
> {
> super(NISTObjectIdentifiers.id_sha256, new SHA256Digest(),
> new PKCS1Encoding(new RSABlindedEngine()));
> }
>
> //MY NEW CODE
> @Override
> protected byte[] getExpected(byte[] hash) throws
> IOException {
> return hash;
> }
>
> }
>
> and then work fine with SHA256 and SHA1.
> Is this modification, in your opinion, correct?
>
> Thanks in advance.
> Andrea Ventura
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic