/// <summary>
        /// Returns the cipher text block size for key in the specified certificate.
        /// </summary>
        protected int GetCipherTextBlockSize(X509Certificate2 receiverCertificate)
        {
            switch (SecurityPolicyUri)
            {
            case SecurityPolicies.Basic256:
            case SecurityPolicies.Basic256Sha256:
            case SecurityPolicies.Aes128_Sha256_RsaOaep:
            {
                return(RsaUtils.GetCipherTextBlockSize(receiverCertificate, RsaUtils.Padding.OaepSHA1));
            }

            case SecurityPolicies.Aes256_Sha256_RsaPss:
            {
                return(RsaUtils.GetCipherTextBlockSize(receiverCertificate, RsaUtils.Padding.OaepSHA256));
            }

            case SecurityPolicies.Basic128Rsa15:
            {
                return(RsaUtils.GetCipherTextBlockSize(receiverCertificate, RsaUtils.Padding.Pkcs1));
            }

            default:
            case SecurityPolicies.None:
            {
                return(1);
            }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Encrypts the message using RSA PKCS#1 v1.5 encryption.
        /// </summary>
        private ArraySegment <byte> Rsa_Encrypt(
            ArraySegment <byte> dataToEncrypt,
            ArraySegment <byte> headerToCopy,
            X509Certificate2 encryptingCertificate,
            bool useOaep)
        {
            RSA rsa = null;

            try
            {
                // get the encrypting key.
                rsa = encryptingCertificate.GetRSAPublicKey();
                if (rsa == null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
                }

                int inputBlockSize  = RsaUtils.GetPlainTextBlockSize(rsa, useOaep);
                int outputBlockSize = RsaUtils.GetCipherTextBlockSize(rsa, useOaep);

                // verify the input data is the correct block size.
                if (dataToEncrypt.Count % inputBlockSize != 0)
                {
                    Utils.Trace("Message is not an integral multiple of the block size. Length = {0}, BlockSize = {1}.", dataToEncrypt.Count, inputBlockSize);
                }

                byte[] encryptedBuffer = BufferManager.TakeBuffer(SendBufferSize, "Rsa_Encrypt");
                Array.Copy(headerToCopy.Array, headerToCopy.Offset, encryptedBuffer, 0, headerToCopy.Count);

                using (MemoryStream ostrm = new MemoryStream(
                           encryptedBuffer,
                           headerToCopy.Count,
                           encryptedBuffer.Length - headerToCopy.Count))
                {
                    // encrypt body.
                    byte[] input = new byte[inputBlockSize];

                    for (int ii = dataToEncrypt.Offset; ii < dataToEncrypt.Offset + dataToEncrypt.Count; ii += inputBlockSize)
                    {
                        Array.Copy(dataToEncrypt.Array, ii, input, 0, input.Length);
                        if (useOaep == true)
                        {
                            byte[] cipherText = rsa.Encrypt(input, RSAEncryptionPadding.OaepSHA1);
                            ostrm.Write(cipherText, 0, cipherText.Length);
                        }
                        else
                        {
                            byte[] cipherText = rsa.Encrypt(input, RSAEncryptionPadding.Pkcs1);
                            ostrm.Write(cipherText, 0, cipherText.Length);
                        }
                    }
                }
                // return buffer
                return(new ArraySegment <byte>(encryptedBuffer, 0, (dataToEncrypt.Count / inputBlockSize) * outputBlockSize + headerToCopy.Count));
            }
            finally
            {
                RsaUtils.RSADispose(rsa);
            }
        }
        /// <summary>
        /// Decrypts the message using RSA encryption.
        /// </summary>
        private ArraySegment <byte> Rsa_Decrypt(
            ArraySegment <byte> dataToDecrypt,
            ArraySegment <byte> headerToCopy,
            X509Certificate2 encryptingCertificate,
            RsaUtils.Padding padding)
        {
            // get the encrypting key.
            using (RSA rsa = encryptingCertificate.GetRSAPrivateKey())
            {
                if (rsa == null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
                }

                int inputBlockSize  = RsaUtils.GetCipherTextBlockSize(rsa, padding);
                int outputBlockSize = RsaUtils.GetPlainTextBlockSize(rsa, padding);

                // verify the input data is the correct block size.
                if (dataToDecrypt.Count % inputBlockSize != 0)
                {
                    Utils.Trace("Message is not an integral multiple of the block size. Length = {0}, BlockSize = {1}.", dataToDecrypt.Count, inputBlockSize);
                }

                byte[] decryptedBuffer = BufferManager.TakeBuffer(SendBufferSize, "Rsa_Decrypt");
                Array.Copy(headerToCopy.Array, headerToCopy.Offset, decryptedBuffer, 0, headerToCopy.Count);
                RSAEncryptionPadding rsaPadding = RsaUtils.GetRSAEncryptionPadding(padding);

                using (MemoryStream ostrm = new MemoryStream(
                           decryptedBuffer,
                           headerToCopy.Count,
                           decryptedBuffer.Length - headerToCopy.Count))
                {
                    // decrypt body.
                    byte[] input = new byte[inputBlockSize];

                    for (int ii = dataToDecrypt.Offset; ii < dataToDecrypt.Offset + dataToDecrypt.Count; ii += inputBlockSize)
                    {
                        Array.Copy(dataToDecrypt.Array, ii, input, 0, input.Length);
                        byte[] plainText = rsa.Decrypt(input, rsaPadding);
                        ostrm.Write(plainText, 0, plainText.Length);
                    }
                }

                // return buffers.
                return(new ArraySegment <byte>(decryptedBuffer, 0, (dataToDecrypt.Count / inputBlockSize) * outputBlockSize + headerToCopy.Count));
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Returns the cipher text block size for key in the specified certificate.
        /// </summary>
        protected int GetCipherTextBlockSize(X509Certificate2 receiverCertificate)
        {
            switch (SecurityPolicyUri)
            {
            case SecurityPolicies.Basic256:
            case SecurityPolicies.Basic256Sha256:
            {
                return(RsaUtils.GetCipherTextBlockSize(receiverCertificate, true));
            }

            case SecurityPolicies.Basic128Rsa15:
            {
                return(RsaUtils.GetCipherTextBlockSize(receiverCertificate, false));
            }

            default:
            case SecurityPolicies.None:
            {
                return(1);
            }
            }
        }