예제 #1
0
        // Apply the private key to a value.
        private byte[] ApplyPrivate(byte[] value)
        {
            if (rsaParams.P != null)
            {
                // Use the Chinese Remainder Theorem exponents.
                // Based on the description in PKCS #1.
                byte[] m1 = CryptoMethods.NumPow(value, rsaParams.DP,
                                                 rsaParams.P);
                byte[] m2 = CryptoMethods.NumPow(value, rsaParams.DQ,
                                                 rsaParams.Q);
                byte[] diff = CryptoMethods.NumSub(m1, m2, null);
                byte[] h    = CryptoMethods.NumMul(diff,
                                                   rsaParams.InverseQ,
                                                   rsaParams.P);
                byte[] prod = CryptoMethods.NumMul(rsaParams.Q, h, null);
                byte[] m    = CryptoMethods.NumAdd(m2, prod, null);

                // Clear all temporary values.
                Array.Clear(m1, 0, m1.Length);
                Array.Clear(m2, 0, m2.Length);
                Array.Clear(diff, 0, diff.Length);
                Array.Clear(h, 0, h.Length);
                Array.Clear(prod, 0, prod.Length);

                // Return the decrypted message.
                return(m);
            }
            else if (rsaParams.D != null)
            {
                // Use the private exponent directly.
                return(CryptoMethods.NumPow(value, rsaParams.D,
                                            rsaParams.Modulus));
            }
            else
            {
                // Insufficient parameters for private key operations.
                throw new CryptographicException
                          (_("Crypto_RSAParamsNotSet"));
            }
        }
예제 #2
0
        // Verify a DSA signature.
        public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature)
        {
            // Validate the parameters.
            if (rgbHash == null)
            {
                throw new ArgumentNullException("rgbHash");
            }
            if (rgbSignature == null)
            {
                throw new ArgumentNullException("rgbSignature");
            }

            // Make sure that we have sufficient parameters to verify.
            if (dsaParams.G == null)
            {
                throw new CryptographicException
                          (_("Crypto_DSAParamsNotSet"));
            }

            // Unpack the signature blob to get R and S.
            ASN1Parser parser;

            parser = (new ASN1Parser(rgbSignature)).GetSequence();
            byte[] R = parser.GetBigInt();
            byte[] S = parser.GetBigInt();
            parser.AtEnd();

            // Compute W = (S^-1 mod Q)
            byte[] W = CryptoMethods.NumInv(S, dsaParams.Q);

            // Compute U1 = ((hash * W) mod Q)
            byte[] U1 = CryptoMethods.NumMul(rgbHash, W, dsaParams.Q);

            // Compute U2 = ((R * W) mod Q)
            byte[] U2 = CryptoMethods.NumMul(R, W, dsaParams.Q);

            // Compute V = (((G^U1 * Y^U2) mod P) mod Q)
            byte[] temp1 = CryptoMethods.NumPow
                               (dsaParams.G, U1, dsaParams.P);
            byte[] temp2 = CryptoMethods.NumPow
                               (dsaParams.Y, U2, dsaParams.P);
            byte[] temp3 = CryptoMethods.NumMul(temp1, temp2, dsaParams.P);
            byte[] V     = CryptoMethods.NumMod(temp3, dsaParams.Q);

            // Determine if we have a signature match.
            bool result = CryptoMethods.NumEq(V, R);

            // Clear sensitive values.
            Array.Clear(R, 0, R.Length);
            Array.Clear(S, 0, S.Length);
            Array.Clear(W, 0, W.Length);
            Array.Clear(U1, 0, U1.Length);
            Array.Clear(U2, 0, U2.Length);
            Array.Clear(temp1, 0, temp1.Length);
            Array.Clear(temp2, 0, temp2.Length);
            Array.Clear(temp3, 0, temp3.Length);
            Array.Clear(V, 0, V.Length);

            // Done.
            return(result);
        }
예제 #3
0
        // Create a DSA signature for the specified data.
        public override byte[] CreateSignature(byte[] rgbHash)
        {
            // Validate the parameter.
            if (rgbHash == null)
            {
                throw new ArgumentNullException("rgbHash");
            }

            // Check that we have sufficient DSA parameters to sign.
            if (dsaParams.G == null)
            {
                throw new CryptographicException
                          (_("Crypto_DSAParamsNotSet"));
            }
            else if (dsaParams.X == null)
            {
                throw new CryptographicException
                          (_("Crypto_CannotSignWithPublic"));
            }

            // Generate a random K less than Q to use in
            // signature generation.  We guarantee less than
            // by setting the high byte of K to at least one
            // less than the high byte of Q.
            int len = dsaParams.Q.Length;

            byte[] K = new byte [len];
            CryptoMethods.GenerateRandom(K, 1, K.Length - 1);
            int index = 0;

            while (index < len && K[index] >= dsaParams.Q[index])
            {
                if (dsaParams.Q[index] == 0)
                {
                    K[index] = (byte)0;
                    ++index;
                }
                else
                {
                    K[index] = (byte)(dsaParams.Q[index] - 1);
                    break;
                }
            }

            // Compute R = ((G^K mod P) mod Q)
            byte[] temp1 = CryptoMethods.NumPow
                               (dsaParams.G, K, dsaParams.P);
            byte[] R = CryptoMethods.NumMod(temp1, dsaParams.Q);
            Array.Clear(temp1, 0, temp1.Length);

            // Compute S = ((K^-1 * (hash + X * R)) mod Q)
            temp1 = CryptoMethods.NumInv(K, dsaParams.Q);
            byte[] temp2 = CryptoMethods.NumMul
                               (dsaParams.X, R, dsaParams.Q);
            byte[] temp3 = CryptoMethods.NumAdd
                               (rgbHash, temp2, dsaParams.Q);
            byte[] S = CryptoMethods.NumMul(temp1, temp3, dsaParams.Q);
            Array.Clear(temp1, 0, temp1.Length);
            Array.Clear(temp2, 0, temp2.Length);
            Array.Clear(temp3, 0, temp3.Length);
            Array.Clear(K, 0, K.Length);

            // Pack R and S into a signature blob and return it.
            ASN1Builder builder = new ASN1Builder();

            builder.AddBigInt(R);
            builder.AddBigInt(S);
            byte[] sig = builder.ToByteArray();
            Array.Clear(R, 0, R.Length);
            Array.Clear(S, 0, S.Length);
            return(sig);
        }