3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <OWNER>[....]</OWNER>
9 namespace System.Security.Cryptography {
10 using System.Globalization;
11 using System.Diagnostics.Contracts;
13 [System.Runtime.InteropServices.ComVisible(true)]
14 public class RSAPKCS1KeyExchangeFormatter : AsymmetricKeyExchangeFormatter {
15 RandomNumberGenerator RngValue;
17 bool? _rsaOverridesEncrypt;
20 // public constructors
23 public RSAPKCS1KeyExchangeFormatter() {}
25 public RSAPKCS1KeyExchangeFormatter(AsymmetricAlgorithm key) {
27 throw new ArgumentNullException("key");
28 Contract.EndContractBlock();
36 public override String Parameters {
37 get { return "<enc:KeyEncryptionMethod enc:Algorithm=\"http://www.microsoft.com/xml/security/algorithm/PKCS1-v1.5-KeyEx\" xmlns:enc=\"http://www.microsoft.com/xml/security/encryption/v1.0\" />"; }
40 public RandomNumberGenerator Rng {
41 get { return RngValue; }
42 set { RngValue = value; }
49 public override void SetKey(AsymmetricAlgorithm key) {
51 throw new ArgumentNullException("key");
52 Contract.EndContractBlock();
54 _rsaOverridesEncrypt = default(bool?);
57 public override byte[] CreateKeyExchange(byte[] rgbData) {
60 throw new ArgumentNullException ("rgbData");
64 throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_MissingKey"));
67 if (OverridesEncrypt) {
68 rgbKeyEx = _rsaKey.Encrypt(rgbData, RSAEncryptionPadding.Pkcs1);
71 int cb = _rsaKey.KeySize/8;
72 if ((rgbData.Length + 11) > cb)
73 throw new CryptographicException(Environment.GetResourceString("Cryptography_Padding_EncDataTooBig", cb-11));
74 byte[] rgbInput = new byte[cb];
77 // We want to pad to the following format:
78 // 00 || 02 || PS || 00 || D
80 // PS - pseudorandom non zero bytes
84 if (RngValue == null) {
85 RngValue = RandomNumberGenerator.Create();
88 Rng.GetNonZeroBytes(rgbInput);
91 rgbInput[cb-rgbData.Length-1] = 0;
92 Buffer.InternalBlockCopy(rgbData, 0, rgbInput, cb-rgbData.Length, rgbData.Length);
95 // Now encrypt the value and return it. (apply public key)
98 rgbKeyEx = _rsaKey.EncryptValue(rgbInput);
103 public override byte[] CreateKeyExchange(byte[] rgbData, Type symAlgType) {
104 return CreateKeyExchange(rgbData);
107 private bool OverridesEncrypt {
109 if (!_rsaOverridesEncrypt.HasValue) {
110 _rsaOverridesEncrypt = Utils.DoesRsaKeyOverride(_rsaKey, "Encrypt", new Type[] { typeof(byte[]), typeof(RSAEncryptionPadding) });
112 return _rsaOverridesEncrypt.Value;