public override void ImportParameters(RSAParameters parameters) { if (parameters.Exponent == null || parameters.Modulus == null) { throw new ArgumentException(Properties.Resources.InvalidRsaParameters); } bool publicOnly = parameters.P == null || parameters.Q == null; // // We need to build a key blob structured as follows: // BCRYPT_RSAKEY_BLOB header // byte[cbPublicExp] publicExponent - Exponent // byte[cbModulus] modulus - Modulus // -- Private only -- // byte[cbPrime1] prime1 - P // byte[cbPrime2] prime2 - Q // int blobSize = Marshal.SizeOf(typeof(BCryptNative.BCRYPT_RSAKEY_BLOB)) + parameters.Exponent.Length + parameters.Modulus.Length; if (!publicOnly) { blobSize += parameters.P.Length + parameters.Q.Length; } byte[] rsaBlob = new byte[blobSize]; unsafe { fixed(byte *pRsaBlob = rsaBlob) { // Build the header BCryptNative.BCRYPT_RSAKEY_BLOB *pBcryptBlob = (BCryptNative.BCRYPT_RSAKEY_BLOB *)pRsaBlob; pBcryptBlob->Magic = publicOnly ? BCryptNative.KeyBlobMagicNumber.RsaPublic : BCryptNative.KeyBlobMagicNumber.RsaPrivate; pBcryptBlob->BitLength = parameters.Modulus.Length * 8; pBcryptBlob->cbPublicExp = parameters.Exponent.Length; pBcryptBlob->cbModulus = parameters.Modulus.Length; if (!publicOnly) { pBcryptBlob->cbPrime1 = parameters.P.Length; pBcryptBlob->cbPrime2 = parameters.Q.Length; } int offset = Marshal.SizeOf(typeof(BCryptNative.BCRYPT_RSAKEY_BLOB)); // Copy the exponent Buffer.BlockCopy(parameters.Exponent, 0, rsaBlob, offset, parameters.Exponent.Length); offset += parameters.Exponent.Length; // Copy the modulus Buffer.BlockCopy(parameters.Modulus, 0, rsaBlob, offset, parameters.Modulus.Length); offset += parameters.Modulus.Length; if (!publicOnly) { // Copy P Buffer.BlockCopy(parameters.P, 0, rsaBlob, offset, parameters.P.Length); offset += parameters.P.Length; // Copy Q Buffer.BlockCopy(parameters.Q, 0, rsaBlob, offset, parameters.Q.Length); offset += parameters.Q.Length; } } } // CngKey.Import will demand KeyContainerPermission since it doesn't know if the RSA blobs contain // an embedded key container name or not. Since we built the blob ourselves, we know that we // didn't specify a key container, so we can assert that demand away. new KeyContainerPermission(KeyContainerPermissionFlags.Import).Assert(); Key = CngKey.Import(rsaBlob, publicOnly ? s_rsaPublicBlob : s_rsaPrivateBlob); CodeAccessPermission.RevertAssert(); }
public override void ImportParameters(RSAParameters parameters) { if (parameters.Exponent == null || parameters.Modulus == null) { throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidRsaParameters)); } bool publicOnly = parameters.P == null || parameters.Q == null; // // We need to build a key blob structured as follows: // BCRYPT_RSAKEY_BLOB header // byte[cbPublicExp] publicExponent - Exponent // byte[cbModulus] modulus - Modulus // -- Private only -- // byte[cbPrime1] prime1 - P // byte[cbPrime2] prime2 - Q // int blobSize = Marshal.SizeOf(typeof(BCryptNative.BCRYPT_RSAKEY_BLOB)) + parameters.Exponent.Length + parameters.Modulus.Length; if (!publicOnly) { blobSize += parameters.P.Length + parameters.Q.Length; } byte[] rsaBlob = new byte[blobSize]; unsafe { fixed(byte *pRsaBlob = rsaBlob) { // Build the header BCryptNative.BCRYPT_RSAKEY_BLOB *pBcryptBlob = (BCryptNative.BCRYPT_RSAKEY_BLOB *)pRsaBlob; pBcryptBlob->Magic = publicOnly ? BCryptNative.KeyBlobMagicNumber.RsaPublic : BCryptNative.KeyBlobMagicNumber.RsaPrivate; pBcryptBlob->BitLength = parameters.Modulus.Length * 8; pBcryptBlob->cbPublicExp = parameters.Exponent.Length; pBcryptBlob->cbModulus = parameters.Modulus.Length; if (!publicOnly) { pBcryptBlob->cbPrime1 = parameters.P.Length; pBcryptBlob->cbPrime2 = parameters.Q.Length; } int offset = Marshal.SizeOf(typeof(BCryptNative.BCRYPT_RSAKEY_BLOB)); // Copy the exponent Buffer.BlockCopy(parameters.Exponent, 0, rsaBlob, offset, parameters.Exponent.Length); offset += parameters.Exponent.Length; // Copy the modulus Buffer.BlockCopy(parameters.Modulus, 0, rsaBlob, offset, parameters.Modulus.Length); offset += parameters.Modulus.Length; if (!publicOnly) { // Copy P Buffer.BlockCopy(parameters.P, 0, rsaBlob, offset, parameters.P.Length); offset += parameters.P.Length; // Copy Q Buffer.BlockCopy(parameters.Q, 0, rsaBlob, offset, parameters.Q.Length); offset += parameters.Q.Length; } } } Key = CngKey.Import(rsaBlob, publicOnly ? s_rsaPublicBlob : s_rsaPrivateBlob); }
public override RSAParameters ExportParameters(bool includePrivateParameters) { byte[] rsaBlob = Key.Export(includePrivateParameters ? s_rsaFullPrivateBlob : s_rsaPublicBlob); RSAParameters rsaParams = new RSAParameters(); // // We now have a buffer laid out as follows: // BCRYPT_RSAKEY_BLOB header // byte[cbPublicExp] publicExponent - Exponent // byte[cbModulus] modulus - Modulus // -- Private only -- // byte[cbPrime1] prime1 - P // byte[cbPrime2] prime2 - Q // byte[cbPrime1] exponent1 - DP // byte[cbPrime2] exponent2 - DQ // byte[cbPrime1] coefficient - InverseQ // byte[cbModulus] privateExponent - D // unsafe { fixed(byte *pRsaBlob = rsaBlob) { BCryptNative.BCRYPT_RSAKEY_BLOB *pBcryptBlob = (BCryptNative.BCRYPT_RSAKEY_BLOB *)pRsaBlob; int offset = Marshal.SizeOf(typeof(BCryptNative.BCRYPT_RSAKEY_BLOB)); // Read out the exponent rsaParams.Exponent = new byte[pBcryptBlob->cbPublicExp]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.Exponent, 0, rsaParams.Exponent.Length); offset += pBcryptBlob->cbPublicExp; // Read out the modulus rsaParams.Modulus = new byte[pBcryptBlob->cbModulus]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.Modulus, 0, rsaParams.Modulus.Length); offset += pBcryptBlob->cbModulus; if (includePrivateParameters) { // Read out P rsaParams.P = new byte[pBcryptBlob->cbPrime1]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.P, 0, rsaParams.P.Length); offset += pBcryptBlob->cbPrime1; // Read out Q rsaParams.Q = new byte[pBcryptBlob->cbPrime2]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.Q, 0, rsaParams.Q.Length); offset += pBcryptBlob->cbPrime2; // Read out DP rsaParams.DP = new byte[pBcryptBlob->cbPrime1]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.DP, 0, rsaParams.DP.Length); offset += pBcryptBlob->cbPrime1; // Read out DQ rsaParams.DQ = new byte[pBcryptBlob->cbPrime2]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.DQ, 0, rsaParams.DQ.Length); offset += pBcryptBlob->cbPrime2; // Read out InverseQ rsaParams.InverseQ = new byte[pBcryptBlob->cbPrime1]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.InverseQ, 0, rsaParams.InverseQ.Length); offset += pBcryptBlob->cbPrime1; // Read out D rsaParams.D = new byte[pBcryptBlob->cbModulus]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.D, 0, rsaParams.D.Length); offset += pBcryptBlob->cbModulus; } } } return(rsaParams); }
public override RSAParameters ExportParameters(bool includePrivateParameters) { byte[] rsaBlob = Key.Export(includePrivateParameters ? s_rsaFullPrivateBlob : s_rsaPublicBlob); RSAParameters rsaParams = new RSAParameters(); // // We now have a buffer laid out as follows: // BCRYPT_RSAKEY_BLOB header // byte[cbPublicExp] publicExponent - Exponent // byte[cbModulus] modulus - Modulus // -- Private only -- // byte[cbPrime1] prime1 - P // byte[cbPrime2] prime2 - Q // byte[cbPrime1] exponent1 - DP // byte[cbPrime2] exponent2 - DQ // byte[cbPrime1] coefficient - InverseQ // byte[cbModulus] privateExponent - D // byte[] tempMagic = new byte[4]; tempMagic[0] = rsaBlob[0]; tempMagic[1] = rsaBlob[1]; tempMagic[2] = rsaBlob[2]; tempMagic[3] = rsaBlob[3]; int magic = BitConverter.ToInt32(tempMagic, 0); //Check the magic value in key blob header. If blob does not have required magic // then it trhows Cryptographic exception CheckMagicValueOfKey(magic, includePrivateParameters); unsafe { fixed(byte *pRsaBlob = rsaBlob) { BCryptNative.BCRYPT_RSAKEY_BLOB *pBcryptBlob = (BCryptNative.BCRYPT_RSAKEY_BLOB *)pRsaBlob; int offset = Marshal.SizeOf(typeof(BCryptNative.BCRYPT_RSAKEY_BLOB)); // Read out the exponent rsaParams.Exponent = new byte[pBcryptBlob->cbPublicExp]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.Exponent, 0, rsaParams.Exponent.Length); offset += pBcryptBlob->cbPublicExp; // Read out the modulus rsaParams.Modulus = new byte[pBcryptBlob->cbModulus]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.Modulus, 0, rsaParams.Modulus.Length); offset += pBcryptBlob->cbModulus; if (includePrivateParameters) { // Read out P rsaParams.P = new byte[pBcryptBlob->cbPrime1]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.P, 0, rsaParams.P.Length); offset += pBcryptBlob->cbPrime1; // Read out Q rsaParams.Q = new byte[pBcryptBlob->cbPrime2]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.Q, 0, rsaParams.Q.Length); offset += pBcryptBlob->cbPrime2; // Read out DP rsaParams.DP = new byte[pBcryptBlob->cbPrime1]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.DP, 0, rsaParams.DP.Length); offset += pBcryptBlob->cbPrime1; // Read out DQ rsaParams.DQ = new byte[pBcryptBlob->cbPrime2]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.DQ, 0, rsaParams.DQ.Length); offset += pBcryptBlob->cbPrime2; // Read out InverseQ rsaParams.InverseQ = new byte[pBcryptBlob->cbPrime1]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.InverseQ, 0, rsaParams.InverseQ.Length); offset += pBcryptBlob->cbPrime1; // Read out D rsaParams.D = new byte[pBcryptBlob->cbModulus]; Buffer.BlockCopy(rsaBlob, offset, rsaParams.D, 0, rsaParams.D.Length); offset += pBcryptBlob->cbModulus; } } } return(rsaParams); }