2 // System.Security.Cryptography.RSA.cs
5 // Dan Lewis (dihlewis@yahoo.co.uk)
6 // Sebastien Pouliot (sebastien@ximian.com)
9 // Portions (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
10 // Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Globalization;
33 using System.Runtime.InteropServices;
38 namespace System.Security.Cryptography {
43 public abstract class RSA : AsymmetricAlgorithm {
45 public static new RSA Create ()
47 return Create ("System.Security.Cryptography.RSA");
50 public static new RSA Create (string algName)
52 return (RSA) CryptoConfig.CreateFromName (algName);
63 public abstract byte[] EncryptValue (byte[] rgb);
65 public abstract byte[] DecryptValue (byte[] rgb);
67 public abstract RSAParameters ExportParameters (bool include);
69 public abstract void ImportParameters (RSAParameters parameters);
71 internal void ZeroizePrivateKey (RSAParameters parameters)
73 if (parameters.P != null)
74 Array.Clear (parameters.P, 0, parameters.P.Length);
75 if (parameters.Q != null)
76 Array.Clear (parameters.Q, 0, parameters.Q.Length);
77 if (parameters.DP != null)
78 Array.Clear (parameters.DP, 0, parameters.DP.Length);
79 if (parameters.DQ != null)
80 Array.Clear (parameters.DQ, 0, parameters.DQ.Length);
81 if (parameters.InverseQ != null)
82 Array.Clear (parameters.InverseQ, 0, parameters.InverseQ.Length);
83 if (parameters.D != null)
84 Array.Clear (parameters.D, 0, parameters.D.Length);
87 private byte[] GetNamedParam (SecurityElement se, string param)
89 SecurityElement sep = se.SearchForChildByTag (param);
92 return Convert.FromBase64String (sep.Text);
95 public override void FromXmlString (string xmlString)
97 if (xmlString == null)
98 throw new ArgumentNullException ("xmlString");
100 RSAParameters rsaParams = new RSAParameters ();
102 SecurityParser sp = new SecurityParser ();
103 sp.LoadXml (xmlString);
104 SecurityElement se = sp.ToXml ();
106 rsaParams.P = GetNamedParam (se, "P");
107 rsaParams.Q = GetNamedParam (se, "Q");
108 rsaParams.D = GetNamedParam (se, "D");
109 rsaParams.DP = GetNamedParam (se, "DP");
110 rsaParams.DQ = GetNamedParam (se, "DQ");
111 rsaParams.InverseQ = GetNamedParam (se, "InverseQ");
112 rsaParams.Exponent = GetNamedParam (se, "Exponent");
113 rsaParams.Modulus = GetNamedParam (se, "Modulus");
114 ImportParameters (rsaParams);
116 catch (Exception e) {
117 ZeroizePrivateKey (rsaParams);
118 throw new CryptographicException (
119 Locale.GetText ("Couldn't decode XML"), e);
122 ZeroizePrivateKey (rsaParams);
126 public override string ToXmlString (bool includePrivateParameters)
128 StringBuilder sb = new StringBuilder ();
129 RSAParameters rsaParams = ExportParameters (includePrivateParameters);
131 sb.Append ("<RSAKeyValue>");
133 sb.Append ("<Modulus>");
134 sb.Append (Convert.ToBase64String (rsaParams.Modulus));
135 sb.Append ("</Modulus>");
137 sb.Append ("<Exponent>");
138 sb.Append (Convert.ToBase64String (rsaParams.Exponent));
139 sb.Append ("</Exponent>");
141 if (includePrivateParameters) {
142 // we want an ArgumentNullException is only the D is missing, but a
143 // CryptographicException if other parameters (CRT) are missings
144 if (rsaParams.D == null) {
145 string msg = Locale.GetText ("Missing D parameter for the private key.");
146 throw new ArgumentNullException (msg);
147 } else if ((rsaParams.P == null) || (rsaParams.Q == null) || (rsaParams.DP == null) ||
148 (rsaParams.DQ == null) || (rsaParams.InverseQ == null)) {
149 // note: we can import a private key, using FromXmlString,
150 // without the CRT parameters but we export it using ToXmlString!
151 string msg = Locale.GetText ("Missing some CRT parameters for the private key.");
152 throw new CryptographicException (msg);
156 sb.Append (Convert.ToBase64String (rsaParams.P));
160 sb.Append (Convert.ToBase64String (rsaParams.Q));
164 sb.Append (Convert.ToBase64String (rsaParams.DP));
168 sb.Append (Convert.ToBase64String (rsaParams.DQ));
171 sb.Append ("<InverseQ>");
172 sb.Append (Convert.ToBase64String (rsaParams.InverseQ));
173 sb.Append ("</InverseQ>");
176 sb.Append (Convert.ToBase64String (rsaParams.D));
180 sb.Append ("</RSAKeyValue>");
183 ZeroizePrivateKey (rsaParams);
187 return sb.ToString ();