示例#1
0
        private byte[] DecodeBlockOrRandom(byte[] input, int inOff, int inLen)
        {
            if (!this.forPrivateKey)
            {
                throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing");
            }
            byte[] array = this.engine.ProcessBlock(input, inOff, inLen);
            byte[] array2;
            if (this.fallback == null)
            {
                array2 = new byte[this.pLen];
                this.random.NextBytes(array2);
            }
            else
            {
                array2 = this.fallback;
            }
            if (array.Length < this.GetOutputBlockSize())
            {
                throw new InvalidCipherTextException("block truncated");
            }
            if (this.useStrictLength && array.Length != this.engine.GetOutputBlockSize())
            {
                throw new InvalidCipherTextException("block incorrect size");
            }
            int num = Pkcs1Encoding.CheckPkcs1Encoding(array, this.pLen);

            byte[] array3 = new byte[this.pLen];
            for (int i = 0; i < this.pLen; i++)
            {
                array3[i] = (byte)(((int)array[i + (array.Length - this.pLen)] & ~num) | ((int)array2[i] & num));
            }
            return(array3);
        }
示例#2
0
        /**
         * Decode PKCS#1.5 encoding, and return a random value if the padding is not correct.
         *
         * @param in The encrypted block.
         * @param inOff Offset in the encrypted block.
         * @param inLen Length of the encrypted block.
         * @param pLen Length of the desired output.
         * @return The plaintext without padding, or a random value if the padding was incorrect.
         *
         * @throws InvalidCipherTextException
         */
        private byte[] DecodeBlockOrRandom(byte[] input, int inOff, int inLen)
        {
            if (!forPrivateKey)
            {
                throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing");
            }

            byte[] block  = engine.ProcessBlock(input, inOff, inLen);
            byte[] random = null;
            if (this.fallback == null)
            {
                random = new byte[this.pLen];
                this.random.NextBytes(random);
            }
            else
            {
                random = fallback;
            }

            /*
             * TODO: This is a potential dangerous side channel. However, you can
             * fix this by changing the RSA engine in a way, that it will always
             * return blocks of the same length and prepend them with 0 bytes if
             * needed.
             */
            if (block.Length < GetOutputBlockSize())
            {
                throw new InvalidCipherTextException("block truncated");
            }

            /*
             * TODO: Potential side channel. Fix it by making the engine always
             * return blocks of the correct length.
             */
            if (useStrictLength && block.Length != engine.GetOutputBlockSize())
            {
                throw new InvalidCipherTextException("block incorrect size");
            }

            /*
             * Check the padding.
             */
            int correct = Pkcs1Encoding.CheckPkcs1Encoding(block, this.pLen);

            /*
             * Now, to a constant time constant memory copy of the decrypted value
             * or the random value, depending on the validity of the padding.
             */
            byte[] result = new byte[this.pLen];
            for (int i = 0; i < this.pLen; i++)
            {
                result[i] = (byte)((block[i + (block.Length - pLen)] & (~correct)) | (random[i] & correct));
            }

            return(result);
        }