Esempio n. 1
0
        /// <summary>
        /// Returns the bytes that represent the symmetric key.
        /// </summary>
        /// <returns>An array of bytes.</returns>
        /// <exception cref="ObjectDisposedException">The SymmetricKey has been disposed.</exception>
        public byte[] ToBytes()
        {
            if (m_Handle == 0)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }
            IntPtr pbSessionBlob = IntPtr.Zero;

            try {
                int dwSessionBlob = 0;
                if (SspiProvider.CryptExportKey(m_Handle, m_ExponentOfOne, SecurityConstants.SIMPLEBLOB, 0, IntPtr.Zero, ref dwSessionBlob) == 0)
                {
                    throw new SecurityException("Cannot export key.");
                }
                pbSessionBlob = Marshal.AllocHGlobal(dwSessionBlob);
                if (SspiProvider.CryptExportKey(m_Handle, m_ExponentOfOne, SecurityConstants.SIMPLEBLOB, 0, pbSessionBlob, ref dwSessionBlob) == 0)
                {
                    throw new SecurityException("Cannot export key.");
                }

                // Get session key size in bits
                int dwSize        = 4;          // sizeof(DWORD)
                int dwKeyMaterial = 0;
                if (SspiProvider.CryptGetKeyParam(m_Handle, SecurityConstants.KP_KEYLEN, ref dwKeyMaterial, ref dwSize, 0) == 0)
                {
                    throw new SecurityException("Cannot retrieve key parameters.");
                }
                // Get the number of bytes and allocate buffer
                dwKeyMaterial /= 8;
                byte[] pbKeyMaterial = new byte[dwKeyMaterial];
                // Skip the header
                int offset = 4 + IntPtr.Size;          // sizeof(BLOBHEADER);
                offset += IntPtr.Size;                 // sizeof(ALG_ID);
                Marshal.Copy(new IntPtr(pbSessionBlob.ToInt64() + offset), pbKeyMaterial, 0, pbKeyMaterial.Length);
                // the key is reversed
                Array.Reverse(pbKeyMaterial);
                return(pbKeyMaterial);
            } finally {
                if (pbSessionBlob != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pbSessionBlob);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Dynamically creates an exponent-of-one key.
        /// </summary>
        /// <returns>The handle of a exponent-of-one key.</returns>
        /// <exception cref="SecurityException">An error occurs while creating the key.</exception>
        private int CreateDynamicExponentOfOneKey()
        {
            int    hPrivateKey = 0;
            int    dwKeyBlob   = 0;
            IntPtr keyblob     = IntPtr.Zero;
            int    dwBitLen;

            try {
                if (SspiProvider.CryptGenKey(m_Provider, new IntPtr(SecurityConstants.AT_KEYEXCHANGE), SecurityConstants.CRYPT_EXPORTABLE, ref hPrivateKey) == 0)
                {
                    throw new SecurityException("Cannot generate key pair.");
                }
                // Export the private key, we'll convert it to a private
                // exponent of one key
                if (SspiProvider.CryptExportKey(hPrivateKey, 0, SecurityConstants.PRIVATEKEYBLOB, 0, IntPtr.Zero, ref dwKeyBlob) == 0)
                {
                    throw new SecurityException("Cannot export generated key.");
                }
                keyblob = Marshal.AllocHGlobal(dwKeyBlob);
                if (SspiProvider.CryptExportKey(hPrivateKey, 0, SecurityConstants.PRIVATEKEYBLOB, 0, keyblob, ref dwKeyBlob) == 0)
                {
                    throw new SecurityException("Cannot export generated key.");
                }
                SspiProvider.CryptDestroyKey(hPrivateKey);
                hPrivateKey = 0;
                // Get the bit length of the key
                dwBitLen = Marshal.ReadInt32(keyblob, 12);
                /* Modify the Exponent in Key BLOB format [Key BLOB format is documented in SDK] */
                // Convert pubexp in rsapubkey to 1
                int offset = 16;
                for (int i = 0; i < 4; i++)
                {
                    if (i == 0)
                    {
                        Marshal.WriteByte(keyblob, offset, 1);
                    }
                    else
                    {
                        Marshal.WriteByte(keyblob, offset + i, 0);
                    }
                }
                // Skip pubexp
                offset += 4;
                // Skip modulus, prime1, prime2
                offset += dwBitLen / 8;
                offset += dwBitLen / 16;
                offset += dwBitLen / 16;
                // Convert exponent1 to 1
                for (int i = 0; i < dwBitLen / 16; i++)
                {
                    if (i == 0)
                    {
                        Marshal.WriteByte(keyblob, offset, 1);
                    }
                    else
                    {
                        Marshal.WriteByte(keyblob, offset + i, 0);
                    }
                }
                // Skip exponent1
                offset += dwBitLen / 16;
                // Convert exponent2 to 1
                for (int i = 0; i < dwBitLen / 16; i++)
                {
                    if (i == 0)
                    {
                        Marshal.WriteByte(keyblob, offset, 1);
                    }
                    else
                    {
                        Marshal.WriteByte(keyblob, offset + i, 0);
                    }
                }
                // Skip exponent2, coefficient
                offset += dwBitLen / 16;
                offset += dwBitLen / 16;
                // Convert privateExponent to 1
                for (int i = 0; i < dwBitLen / 8; i++)
                {
                    if (i == 0)
                    {
                        Marshal.WriteByte(keyblob, offset, 1);
                    }
                    else
                    {
                        Marshal.WriteByte(keyblob, offset + i, 0);
                    }
                }
                // Import the exponent-of-one private key.
                if (SspiProvider.CryptImportKey(m_Provider, keyblob, dwKeyBlob, 0, SecurityConstants.CRYPT_EXPORTABLE, ref hPrivateKey) == 0)
                {
                    throw new SecurityException("Could not import modified key.");
                }
            } catch (Exception e) {
                if (hPrivateKey != 0)
                {
                    SspiProvider.CryptDestroyKey(hPrivateKey);
                }
                throw e;
            } finally {
                if (keyblob != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(keyblob);
                }
            }
            return(hPrivateKey);
        }