コード例 #1
0
        /// <summary>
        /// Computes a RSA signature.
        /// </summary>
        internal static byte[] Rsa_Sign(
            ArraySegment <byte> dataToSign,
            X509Certificate2 signingCertificate,
            HashAlgorithmName hashAlgorithm,
            RSASignaturePadding rsaSignaturePadding)
        {
            RSA rsa = null;

            try
            {
                // extract the private key.
                rsa = signingCertificate.GetRSAPrivateKey();
                if (rsa == null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
                }

                // create the signature.
                return(rsa.SignData(dataToSign.Array, dataToSign.Offset, dataToSign.Count, hashAlgorithm, rsaSignaturePadding));
            }
            finally
            {
                RsaUtils.RSADispose(rsa);
            }
        }
コード例 #2
0
        /// <summary>
        /// Verifies a RSA signature.
        /// </summary>
        internal static bool Rsa_Verify(
            ArraySegment <byte> dataToVerify,
            byte[] signature,
            X509Certificate2 signingCertificate,
            HashAlgorithmName hashAlgorithm,
            RSASignaturePadding rsaSignaturePadding)
        {
            RSA rsa = null;

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

                // verify signature.
                return(rsa.VerifyData(dataToVerify.Array, dataToVerify.Offset, dataToVerify.Count, signature, hashAlgorithm, rsaSignaturePadding));
            }
            finally
            {
                RsaUtils.RSADispose(rsa);
            }
        }
コード例 #3
0
        /// <summary>
        /// Create a X509Certificate2 with a private key by combining
        /// the new certificate with a private key from an existing certificate
        /// </summary>
        public static X509Certificate2 CreateCertificateWithPrivateKey(
            X509Certificate2 certificate,
            X509Certificate2 certificateWithPrivateKey)
        {
            if (!certificateWithPrivateKey.HasPrivateKey)
            {
                throw new NotSupportedException("Need a certificate with a private key.");
            }

            if (!X509Utils.VerifyRSAKeyPair(certificate, certificateWithPrivateKey))
            {
                throw new NotSupportedException("The public and the private key pair doesn't match.");
            }

            string passcode      = Guid.NewGuid().ToString();
            RSA    rsaPrivateKey = null;

            try
            {
                rsaPrivateKey = certificateWithPrivateKey.GetRSAPrivateKey();
                byte[] pfxData = CertificateBuilder.CreatePfxWithRSAPrivateKey(
                    certificate, certificate.FriendlyName, rsaPrivateKey, passcode);
                return(X509Utils.CreateCertificateFromPKCS12(pfxData, passcode));
            }
            finally
            {
                RsaUtils.RSADispose(rsaPrivateKey);
            }
        }
コード例 #4
0
        /// <summary>
        /// Return the ciphertext block size for RSA OAEP encryption.
        /// </summary>
        internal static int GetCipherTextBlockSize(X509Certificate2 encryptingCertificate, Padding padding)
        {
            RSA rsa = null;

            try
            {
                rsa = encryptingCertificate.GetRSAPublicKey();
                return(GetCipherTextBlockSize(rsa, padding));
            }
            finally
            {
                RsaUtils.RSADispose(rsa);
            }
        }
コード例 #5
0
        /// <summary>
        /// Returns the size of the public key and disposes RSA key.
        /// </summary>
        /// <param name="certificate">The certificate</param>
        public static int GetRSAPublicKeySize(X509Certificate2 certificate)
        {
            RSA rsaPublicKey = null;

            try
            {
                rsaPublicKey = certificate.GetRSAPublicKey();
                return(rsaPublicKey.KeySize);
            }
            finally
            {
                RsaUtils.RSADispose(rsaPublicKey);
            }
        }
コード例 #6
0
        /// <summary>
        /// Return the ciphertext block size for RSA OAEP encryption.
        /// </summary>
        public static int GetCipherTextBlockSize(X509Certificate2 encryptingCertificate, bool useOaep)
        {
            RSA rsa = null;

            try
            {
                rsa = encryptingCertificate.GetRSAPublicKey();
                return(GetCipherTextBlockSize(rsa, useOaep));
            }
            finally
            {
                RsaUtils.RSADispose(rsa);
            }
        }
コード例 #7
0
ファイル: RsaUtils.cs プロジェクト: torikachi24/ASPCLientWeb
        /// <summary>
        /// Decrypts the data using RSA encryption.
        /// </summary>
        internal static byte[] Decrypt(
            ArraySegment <byte> dataToDecrypt,
            X509Certificate2 encryptingCertificate,
            Padding padding)
        {
            RSA rsa = null;

            try
            {
                rsa = encryptingCertificate.GetRSAPrivateKey();
                if (rsa == null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
                }

                int plainTextSize = dataToDecrypt.Count / GetCipherTextBlockSize(rsa, padding);
                plainTextSize *= GetPlainTextBlockSize(encryptingCertificate, padding);

                byte[] buffer = new byte[plainTextSize];
                ArraySegment <byte> plainText = Decrypt(dataToDecrypt, rsa, padding, new ArraySegment <byte>(buffer));
                System.Diagnostics.Debug.Assert(plainText.Count == buffer.Length);

                // decode length.
                int length = 0;

                length += (((int)plainText.Array[plainText.Offset + 0]));
                length += (((int)plainText.Array[plainText.Offset + 1]) << 8);
                length += (((int)plainText.Array[plainText.Offset + 2]) << 16);
                length += (((int)plainText.Array[plainText.Offset + 3]) << 24);

                if (length > (plainText.Count - plainText.Offset - 4))
                {
                    throw ServiceResultException.Create(StatusCodes.BadEndOfStream, "Could not decrypt data. Invalid total length.");
                }

                byte[] decryptedData = new byte[length];
                Array.Copy(plainText.Array, plainText.Offset + 4, decryptedData, 0, length);

                return(decryptedData);
            }
            finally
            {
                RsaUtils.RSADispose(rsa);
            }
        }
コード例 #8
0
        /// <summary>
        /// Returns the length of a RSA PKCS#1 v1.5 signature of a digest.
        /// </summary>
        internal static int GetSignatureLength(X509Certificate2 signingCertificate)
        {
            RSA rsa = null;

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

                return(rsa.KeySize / 8);
            }
            finally
            {
                RsaUtils.RSADispose(rsa);
            }
        }
コード例 #9
0
        /// <summary>
        /// Encrypts the data using RSA encryption.
        /// </summary>
        internal static byte[] Encrypt(
            byte[] dataToEncrypt,
            X509Certificate2 encryptingCertificate,
            Padding padding)
        {
            RSA rsa = null;

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

                int plaintextBlockSize = GetPlainTextBlockSize(rsa, padding);
                int blockCount         = ((dataToEncrypt.Length + 4) / plaintextBlockSize) + 1;
                int plainTextSize      = blockCount * plaintextBlockSize;
                int cipherTextSize     = blockCount * GetCipherTextBlockSize(rsa, padding);

                byte[] plainText = new byte[plainTextSize];

                // encode length.
                plainText[0] = (byte)((0x000000FF & dataToEncrypt.Length));
                plainText[1] = (byte)((0x0000FF00 & dataToEncrypt.Length) >> 8);
                plainText[2] = (byte)((0x00FF0000 & dataToEncrypt.Length) >> 16);
                plainText[3] = (byte)((0xFF000000 & dataToEncrypt.Length) >> 24);

                // copy data.
                Array.Copy(dataToEncrypt, 0, plainText, 4, dataToEncrypt.Length);

                byte[] buffer = new byte[cipherTextSize];
                ArraySegment <byte> cipherText = Encrypt(new ArraySegment <byte>(plainText), rsa, padding, new ArraySegment <byte>(buffer));
                System.Diagnostics.Debug.Assert(cipherText.Count == buffer.Length);

                return(buffer);
            }
            finally
            {
                RsaUtils.RSADispose(rsa);
            }
        }