Beispiel #1
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>
        /// Returns the plain text block size for key in the specified certificate.
        /// </summary>
        protected int GetPlainTextBlockSize(X509Certificate2 receiverCertificate)
        {
            switch (SecurityPolicyUri)
            {
            case SecurityPolicies.Basic256:
            case SecurityPolicies.Basic256Sha256:
            case SecurityPolicies.Aes128_Sha256_RsaOaep:
            {
                return(RsaUtils.GetPlainTextBlockSize(receiverCertificate, RsaUtils.Padding.OaepSHA1));
            }

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

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

            default:
            case SecurityPolicies.None:
            {
                return(1);
            }
            }
        }
    private static bool VerifyRSAKeyPairSign(
        RSA rsaPublicKey,
        RSA rsaPrivateKey)
    {
        Opc.Ua.Test.RandomSource randomSource = new Opc.Ua.Test.RandomSource();
        int blockSize = RsaUtils.GetPlainTextBlockSize(rsaPrivateKey, true);

        byte[] testBlock = new byte[blockSize];
        randomSource.NextBytes(testBlock, 0, blockSize);
        byte[] signature = rsaPrivateKey.SignData(testBlock, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
        return(rsaPublicKey.VerifyData(testBlock, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));
    }
        /// <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));
            }
        }
    private static bool VerifyRSAKeyPairCrypt(
        RSA rsaPublicKey,
        RSA rsaPrivateKey)
    {
        Opc.Ua.Test.RandomSource randomSource = new Opc.Ua.Test.RandomSource();
        int blockSize = RsaUtils.GetPlainTextBlockSize(rsaPrivateKey, true);

        byte[] testBlock = new byte[blockSize];
        randomSource.NextBytes(testBlock, 0, blockSize);
        byte[] encryptedBlock = rsaPublicKey.Encrypt(testBlock, RSAEncryptionPadding.OaepSHA1);
        byte[] decryptedBlock = rsaPrivateKey.Decrypt(encryptedBlock, RSAEncryptionPadding.OaepSHA1);
        if (decryptedBlock != null)
        {
            return(Utils.IsEqual(testBlock, decryptedBlock));
        }
        return(false);
    }
    /// <summary>
    /// Verify RSA key pair of two certificates.
    /// </summary>
    private static bool VerifyRSAKeyPair(
        X509Certificate2 certWithPublicKey,
        X509Certificate2 certWithPrivateKey,
        bool throwOnError = false)
    {
        bool result = false;

        try
        {
            // verify the public and private key match
            using (RSA rsaPrivateKey = certWithPrivateKey.GetRSAPrivateKey())
            {
                using (RSA rsaPublicKey = certWithPublicKey.GetRSAPublicKey())
                {
                    Opc.Ua.Test.RandomSource randomSource = new Opc.Ua.Test.RandomSource();
                    int    blockSize = RsaUtils.GetPlainTextBlockSize(rsaPrivateKey, true);
                    byte[] testBlock = new byte[blockSize];
                    randomSource.NextBytes(testBlock, 0, blockSize);
                    byte[] encryptedBlock = rsaPublicKey.Encrypt(testBlock, RSAEncryptionPadding.OaepSHA1);
                    byte[] decryptedBlock = rsaPrivateKey.Decrypt(encryptedBlock, RSAEncryptionPadding.OaepSHA1);
                    if (decryptedBlock != null)
                    {
                        result = Utils.IsEqual(testBlock, decryptedBlock);
                    }
                }
            }
        }
        catch (Exception e)
        {
            if (throwOnError)
            {
                throw e;
            }
        }
        finally
        {
            if (!result && throwOnError)
            {
                throw new CryptographicException("The public/private key pair in the certficates do not match.");
            }
        }
        return(result);
    }
Beispiel #7
0
        /// <summary>
        /// Returns the plain text block size for key in the specified certificate.
        /// </summary>
        protected int GetPlainTextBlockSize(X509Certificate2 receiverCertificate)
        {
            switch (SecurityPolicyUri)
            {
            case SecurityPolicies.Basic256:
            case SecurityPolicies.Basic256Sha256:
            {
                return(RsaUtils.GetPlainTextBlockSize(receiverCertificate, true));
            }

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

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