ISO9796-2 - mechanism using a hash function with recovery (scheme 1)
Наследование: ISignerWithRecovery
Пример #1
0
        /// <summary>
        /// Check an Active Authentication reply from the passport.
        /// </summary>
        /// <param name="publicKey">The AA public key read from the passport.</param>
        /// <param name="message">The original message.</param>
        /// <param name="signature">The response from the passport</param>
        /// <returns>True if the signature is correct for this message.</returns>
        public static bool CheckAA(RsaPublicKeyStructure publicKey, byte[] message, byte[] signature)
        {
            SHA1 sha1 = SHA1.Create();
            RsaEngine rsa = new RsaEngine();
            RsaKeyParameters p = new RsaKeyParameters(false, publicKey.Modulus, publicKey.PublicExponent);
            rsa.Init(false, p);

            byte[] digestedMessage = sha1.ComputeHash(message); // should always be 20 bytes
            byte[] m2 = new byte[8];
            Array.Copy(digestedMessage, 0, m2, 0, m2.Length);
            byte[] plainText = rsa.ProcessBlock(signature, 0, signature.Length);
            byte[] m1 = recoverMessage(digestedMessage.Length, plainText);

            Sha1Digest digest = new Sha1Digest();
            Iso9796d2Signer signer = new Iso9796d2Signer(rsa, digest);
            signer.Init(false, p);
            signer.BlockUpdate(m1, 0, m1.Length);
            signer.BlockUpdate(m2, 0, m2.Length);
            return signer.VerifySignature(signature);
        }
Пример #2
0
        public void DoTest13()
        {
            BigInteger modulus = new BigInteger(1, Hex.Decode("CDCBDABBF93BE8E8294E32B055256BBD0397735189BF75816341BB0D488D05D627991221DF7D59835C76A4BB4808ADEEB779E7794504E956ADC2A661B46904CDC71337DD29DDDD454124EF79CFDD7BC2C21952573CEFBA485CC38C6BD2428809B5A31A898A6B5648CAA4ED678D9743B589134B7187478996300EDBA16271A861"));
            BigInteger pubExp = new BigInteger(1, Hex.Decode("010001"));
            BigInteger privExp = new BigInteger(1, Hex.Decode("4BA6432AD42C74AA5AFCB6DF60FD57846CBC909489994ABD9C59FE439CC6D23D6DE2F3EA65B8335E796FD7904CA37C248367997257AFBD82B26F1A30525C447A236C65E6ADE43ECAAF7283584B2570FA07B340D9C9380D88EAACFFAEEFE7F472DBC9735C3FF3A3211E8A6BBFD94456B6A33C17A2C4EC18CE6335150548ED126D"));

            RsaKeyParameters pubParams = new RsaKeyParameters(false, modulus, pubExp);
            RsaKeyParameters privParams = new RsaKeyParameters(true, modulus, privExp);

            IAsymmetricBlockCipher rsaEngine = new RsaBlindedEngine();
            IDigest digest = new Sha256Digest();

            // set challenge to all zero's for verification
            byte[] challenge = new byte[8];

            // DOES NOT USE FINAL BOOLEAN TO INDICATE RECOVERY
            Iso9796d2Signer signer = new Iso9796d2Signer(rsaEngine, digest, false);

            // sign
            signer.Init(true, privParams);
            signer.BlockUpdate(challenge, 0, challenge.Length);

            byte[]  sig = signer.GenerateSignature();

            // verify
            signer.Init(false, pubParams);
            signer.BlockUpdate(challenge, 0, challenge.Length);

            if (!signer.VerifySignature(sig))
            {
                Fail("basic verification failed");
            }

            // === LETS ACTUALLY DO SOME RECOVERY, USING INPUT FROM INTERNAL AUTHENTICATE ===

            signer.Reset();

            string args0 = "482E20D1EDDED34359C38F5E7C01203F9D6B2641CDCA5C404D49ADAEDE034C7481D781D043722587761C90468DE69C6585A1E8B9C322F90E1B580EEDAB3F6007D0C366CF92B4DB8B41C8314929DCE2BE889C0129123484D2FD3D12763D2EBFD12AC8E51D7061AFCA1A53DEDEC7B9A617472A78C952CCC72467AE008E5F132994";

            digest = new Sha1Digest();

            signer = new Iso9796d2Signer(rsaEngine, digest, true);


            signer.Init(false, pubParams);
            byte[] signature = Hex.Decode(args0);
            signer.UpdateWithRecoveredMessage(signature);
            signer.BlockUpdate(challenge, 0, challenge.Length);

            if (!signer.VerifySignature(signature))
            {
                Fail("recovered + challenge signature failed");
            }

            // === FINALLY, USING SHA-256 ===

            signer.Reset();

            digest = new Sha256Digest();

            // NOTE setting implicit to false does not actually do anything for verification !!!
            signer = new Iso9796d2Signer(rsaEngine, digest, false);


            signer.Init(true, privParams);
            // generate NONCE of correct length using some inner knowledge
            int nonceLength = modulus.BitLength / 8 - 1 - digest.GetDigestSize() - 2;
            byte[] nonce = new byte[nonceLength];
            SecureRandom rnd = new SecureRandom();

            rnd.NextBytes(nonce);

            signer.BlockUpdate(nonce, 0, nonce.Length);
            signer.BlockUpdate(challenge, 0, challenge.Length);
            byte[] sig3 = signer.GenerateSignature();

            signer.Init(false, pubParams);
            signer.UpdateWithRecoveredMessage(sig3);
            signer.BlockUpdate(challenge, 0, challenge.Length);
            if (signer.VerifySignature(sig3))
            {
                if (signer.HasFullMessage())
                {
                    Fail("signer indicates full message");
                }
                byte[] recoverableMessage = signer.GetRecoveredMessage();

                // sanity check, normally the nonce is ignored in eMRTD specs (PKI Technical Report)
                if (!Arrays.AreEqual(nonce, recoverableMessage))
                {
                    Fail("Nonce compare with recoverable part of message failed");
                }
            }
            else
            {
                Fail("recoverable + nonce failed.");
            }
        }
Пример #3
0
        public virtual void DoTest12()
        {
            BigInteger          mod = new BigInteger("B3ABE6D91A4020920F8B3847764ECB34C4EB64151A96FDE7B614DC986C810FF2FD73575BDF8532C06004C8B4C8B64F700A50AEC68C0701ED10E8D211A4EA554D", 16);
            BigInteger          pubExp = new BigInteger("65537", 10);
            BigInteger          priExp = new BigInteger("AEE76AE4716F77C5782838F328327012C097BD67E5E892E75C1356E372CCF8EE1AA2D2CBDFB4DA19F703743F7C0BA42B2D69202BA7338C294D1F8B6A5771FF41", 16);
            RsaKeyParameters    pubParameters = new RsaKeyParameters(false, mod, pubExp);
            RsaKeyParameters    privParameters = new RsaKeyParameters(true, mod, priExp);
            RsaEngine           rsa = new RsaEngine();
            byte[]              data;
            byte[]              m1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            byte[]              m2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
            byte[]              m3 = { 1, 2, 3, 4, 5, 6, 7, 8 };

            //
            // ISO 9796-2 - Regular Signing
            //
            IDigest           dig = new Sha1Digest();
            Iso9796d2Signer  eng = new Iso9796d2Signer(rsa, dig);

            //
            // check message bounds
            //
            eng.Init(true, privParameters);

            eng.BlockUpdate(m1, 0, m1.Length);

            data = eng.GenerateSignature();

            eng.Init(false, pubParameters);

            eng.BlockUpdate(m2, 0, m2.Length);

            if (eng.VerifySignature(data))
            {
                Fail("failed ISO9796-2 m2 verify Test 12");
            }

            eng.Init(false, pubParameters);

            eng.BlockUpdate(m3, 0, m3.Length);

            if (eng.VerifySignature(data))
            {
                Fail("failed ISO9796-2 m3 verify Test 12");
            }

            eng.Init(false, pubParameters);

            eng.BlockUpdate(m1, 0, m1.Length);

            if (!eng.VerifySignature(data))
            {
                Fail("failed ISO9796-2 verify Test 12");
            }
        }
Пример #4
0
        public virtual void DoTest5()
        {
            RsaKeyParameters pubParameters = new RsaKeyParameters(false, mod3, pub3);
            RsaKeyParameters privParameters = new RsaKeyParameters(true, mod3, pri3);
            RsaEngine rsa = new RsaEngine();
            byte[] data;

            //
            // ISO 9796-2 - Signing
            //
            Iso9796d2Signer eng = new Iso9796d2Signer(rsa, new RipeMD160Digest(), true);

            eng.Init(true, privParameters);

            eng.Update(msg5[0]);
            eng.BlockUpdate(msg5, 1, msg5.Length - 1);

            data = eng.GenerateSignature();

            eng.Init(false, pubParameters);

            if (!IsSameAs(sig5, 0, data))
            {
                Fail("failed ISO9796-2 generation Test 5");
            }

            eng.Update(msg5[0]);
            eng.BlockUpdate(msg5, 1, msg5.Length - 1);

            if (!eng.VerifySignature(data))
            {
                Fail("failed ISO9796-2 verify Test 5");
            }

            if (eng.HasFullMessage())
            {
                Fail("fullMessage true - Test 5");
            }

            if (!StartsWith(msg5, eng.GetRecoveredMessage()))
            {
                Fail("failed ISO9796-2 partial recovered message Test 5");
            }

            int length = eng.GetRecoveredMessage().Length;

            if (length >= msg5.Length)
            {
                Fail("Test 5 recovered message too long");
            }

            eng = new Iso9796d2Signer(rsa, new RipeMD160Digest(), true);

            eng.Init(false, pubParameters);

            eng.UpdateWithRecoveredMessage(sig5);

            if (!StartsWith(msg5, eng.GetRecoveredMessage()))
            {
                Fail("failed ISO9796-2 updateWithRecovered partial recovered message Test 5");
            }

            if (eng.HasFullMessage())
            {
                Fail("fullMessage updateWithRecovered true - Test 5");
            }

            for (int i = length ; i != msg5.Length; i++)
            {
                eng.Update(msg5[i]);
            }

            if (!eng.VerifySignature(sig5))
            {
                Fail("failed ISO9796-2 verify Test 5");
            }

            if (eng.HasFullMessage())
            {
                Fail("fullMessage updateWithRecovered true - Test 5");
            }

            // should fail
            eng.UpdateWithRecoveredMessage(sig5);

            eng.BlockUpdate(msg5, 0, msg5.Length);

            if (eng.VerifySignature(sig5))
            {
                Fail("failed ISO9796-2 updateWithRecovered verify fail Test 5");
            }
        }
Пример #5
0
        public virtual void DoTest4()
        {
            RsaKeyParameters pubParameters = new RsaKeyParameters(false, mod3, pub3);
            RsaKeyParameters privParameters = new RsaKeyParameters(true, mod3, pri3);
            RsaEngine rsa = new RsaEngine();
            byte[] data;

            //
            // ISO 9796-2 - Signing
            //
            Iso9796d2Signer eng = new Iso9796d2Signer(rsa, new RipeMD128Digest());

            eng.Init(true, privParameters);

            eng.Update(msg4[0]);
            eng.BlockUpdate(msg4, 1, msg4.Length - 1);

            data = eng.GenerateSignature();

            eng.Init(false, pubParameters);

            if (!IsSameAs(sig4, 0, data))
            {
                Fail("failed ISO9796-2 generation Test 4");
            }

            eng.Update(msg4[0]);
            eng.BlockUpdate(msg4, 1, msg4.Length - 1);

            if (!eng.VerifySignature(data))
            {
                Fail("failed ISO9796-2 verify Test 4");
            }

            if (eng.HasFullMessage())
            {
                eng = new Iso9796d2Signer(rsa, new RipeMD128Digest());

                eng.Init(false, pubParameters);

                if (!eng.VerifySignature(sig4))
                {
                    Fail("failed ISO9796-2 verify and recover Test 4");
                }

                if(!IsSameAs(eng.GetRecoveredMessage(), 0, msg4))
                {
                    Fail("failed ISO9796-2 recovered message Test 4");
                }

                // try update with recovered
                eng.UpdateWithRecoveredMessage(sig4);

                if(!IsSameAs(eng.GetRecoveredMessage(), 0, msg4))
                {
                    Fail("failed ISO9796-2 updateWithRecovered recovered message Test 4");
                }
                
                if (!eng.VerifySignature(sig4))
                {
                    Fail("failed ISO9796-2 updateWithRecovered verify and recover Test 4");
                }
                
                if(!IsSameAs(eng.GetRecoveredMessage(), 0, msg4))
                {
                    Fail("failed ISO9796-2 updateWithRecovered recovered verify message Test 4");
                }
                
                // should fail
                eng.UpdateWithRecoveredMessage(sig4);
                
                eng.BlockUpdate(msg4, 0, msg4.Length);
                
                if (eng.VerifySignature(sig4))
                {
                    Fail("failed ISO9796-2 updateWithRecovered verify and recover Test 4");
                }
            }
            else
            {
                Fail("full message flag false - Test 4");
            }
        }