DotNetUtilities.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #if !(NETCF_1_0 || SILVERLIGHT || PORTABLE)
  2. using System;
  3. using System.Security.Cryptography;
  4. using SystemX509 = System.Security.Cryptography.X509Certificates;
  5. using Essensoft.AspNetCore.Security.Asn1.Pkcs;
  6. using Essensoft.AspNetCore.Security.Asn1.X509;
  7. using Essensoft.AspNetCore.Security.Parameters;
  8. using Essensoft.AspNetCore.Security.Math;
  9. using Essensoft.AspNetCore.Security.X509;
  10. namespace Essensoft.AspNetCore.Security.Security
  11. {
  12. /// <summary>
  13. /// A class containing methods to interface the BouncyCastle world to the .NET Crypto world.
  14. /// </summary>
  15. public sealed class DotNetUtilities
  16. {
  17. private DotNetUtilities()
  18. {
  19. }
  20. /// <summary>
  21. /// Create an System.Security.Cryptography.X509Certificate from an X509Certificate Structure.
  22. /// </summary>
  23. /// <param name="x509Struct"></param>
  24. /// <returns>A System.Security.Cryptography.X509Certificate.</returns>
  25. public static SystemX509.X509Certificate ToX509Certificate(
  26. X509CertificateStructure x509Struct)
  27. {
  28. return new SystemX509.X509Certificate(x509Struct.GetDerEncoded());
  29. }
  30. public static SystemX509.X509Certificate ToX509Certificate(
  31. X509Certificate x509Cert)
  32. {
  33. return new SystemX509.X509Certificate(x509Cert.GetEncoded());
  34. }
  35. public static X509Certificate FromX509Certificate(
  36. SystemX509.X509Certificate x509Cert)
  37. {
  38. return new X509CertificateParser().ReadCertificate(x509Cert.GetRawCertData());
  39. }
  40. public static AsymmetricCipherKeyPair GetDsaKeyPair(
  41. DSA dsa)
  42. {
  43. return GetDsaKeyPair(dsa.ExportParameters(true));
  44. }
  45. public static AsymmetricCipherKeyPair GetDsaKeyPair(
  46. DSAParameters dp)
  47. {
  48. DsaValidationParameters validationParameters = (dp.Seed != null)
  49. ? new DsaValidationParameters(dp.Seed, dp.Counter)
  50. : null;
  51. DsaParameters parameters = new DsaParameters(
  52. new BigInteger(1, dp.P),
  53. new BigInteger(1, dp.Q),
  54. new BigInteger(1, dp.G),
  55. validationParameters);
  56. DsaPublicKeyParameters pubKey = new DsaPublicKeyParameters(
  57. new BigInteger(1, dp.Y),
  58. parameters);
  59. DsaPrivateKeyParameters privKey = new DsaPrivateKeyParameters(
  60. new BigInteger(1, dp.X),
  61. parameters);
  62. return new AsymmetricCipherKeyPair(pubKey, privKey);
  63. }
  64. public static DsaPublicKeyParameters GetDsaPublicKey(
  65. DSA dsa)
  66. {
  67. return GetDsaPublicKey(dsa.ExportParameters(false));
  68. }
  69. public static DsaPublicKeyParameters GetDsaPublicKey(
  70. DSAParameters dp)
  71. {
  72. DsaValidationParameters validationParameters = (dp.Seed != null)
  73. ? new DsaValidationParameters(dp.Seed, dp.Counter)
  74. : null;
  75. DsaParameters parameters = new DsaParameters(
  76. new BigInteger(1, dp.P),
  77. new BigInteger(1, dp.Q),
  78. new BigInteger(1, dp.G),
  79. validationParameters);
  80. return new DsaPublicKeyParameters(
  81. new BigInteger(1, dp.Y),
  82. parameters);
  83. }
  84. public static AsymmetricCipherKeyPair GetRsaKeyPair(
  85. RSA rsa)
  86. {
  87. return GetRsaKeyPair(rsa.ExportParameters(true));
  88. }
  89. public static AsymmetricCipherKeyPair GetRsaKeyPair(
  90. RSAParameters rp)
  91. {
  92. BigInteger modulus = new BigInteger(1, rp.Modulus);
  93. BigInteger pubExp = new BigInteger(1, rp.Exponent);
  94. RsaKeyParameters pubKey = new RsaKeyParameters(
  95. false,
  96. modulus,
  97. pubExp);
  98. RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters(
  99. modulus,
  100. pubExp,
  101. new BigInteger(1, rp.D),
  102. new BigInteger(1, rp.P),
  103. new BigInteger(1, rp.Q),
  104. new BigInteger(1, rp.DP),
  105. new BigInteger(1, rp.DQ),
  106. new BigInteger(1, rp.InverseQ));
  107. return new AsymmetricCipherKeyPair(pubKey, privKey);
  108. }
  109. public static RsaKeyParameters GetRsaPublicKey(
  110. RSA rsa)
  111. {
  112. return GetRsaPublicKey(rsa.ExportParameters(false));
  113. }
  114. public static RsaKeyParameters GetRsaPublicKey(
  115. RSAParameters rp)
  116. {
  117. return new RsaKeyParameters(
  118. false,
  119. new BigInteger(1, rp.Modulus),
  120. new BigInteger(1, rp.Exponent));
  121. }
  122. public static AsymmetricCipherKeyPair GetKeyPair(AsymmetricAlgorithm privateKey)
  123. {
  124. if (privateKey is DSA)
  125. {
  126. return GetDsaKeyPair((DSA)privateKey);
  127. }
  128. if (privateKey is RSA)
  129. {
  130. return GetRsaKeyPair((RSA)privateKey);
  131. }
  132. throw new ArgumentException("Unsupported algorithm specified", "privateKey");
  133. }
  134. public static RSA ToRSA(RsaKeyParameters rsaKey)
  135. {
  136. // TODO This appears to not work for private keys (when no CRT info)
  137. return CreateRSAProvider(ToRSAParameters(rsaKey));
  138. }
  139. public static RSA ToRSA(RsaPrivateCrtKeyParameters privKey)
  140. {
  141. return CreateRSAProvider(ToRSAParameters(privKey));
  142. }
  143. public static RSA ToRSA(RsaPrivateKeyStructure privKey)
  144. {
  145. return CreateRSAProvider(ToRSAParameters(privKey));
  146. }
  147. public static RSAParameters ToRSAParameters(RsaKeyParameters rsaKey)
  148. {
  149. RSAParameters rp = new RSAParameters();
  150. rp.Modulus = rsaKey.Modulus.ToByteArrayUnsigned();
  151. if (rsaKey.IsPrivate)
  152. rp.D = ConvertRSAParametersField(rsaKey.Exponent, rp.Modulus.Length);
  153. else
  154. rp.Exponent = rsaKey.Exponent.ToByteArrayUnsigned();
  155. return rp;
  156. }
  157. public static RSAParameters ToRSAParameters(RsaPrivateCrtKeyParameters privKey)
  158. {
  159. RSAParameters rp = new RSAParameters();
  160. rp.Modulus = privKey.Modulus.ToByteArrayUnsigned();
  161. rp.Exponent = privKey.PublicExponent.ToByteArrayUnsigned();
  162. rp.P = privKey.P.ToByteArrayUnsigned();
  163. rp.Q = privKey.Q.ToByteArrayUnsigned();
  164. rp.D = ConvertRSAParametersField(privKey.Exponent, rp.Modulus.Length);
  165. rp.DP = ConvertRSAParametersField(privKey.DP, rp.P.Length);
  166. rp.DQ = ConvertRSAParametersField(privKey.DQ, rp.Q.Length);
  167. rp.InverseQ = ConvertRSAParametersField(privKey.QInv, rp.Q.Length);
  168. return rp;
  169. }
  170. public static RSAParameters ToRSAParameters(RsaPrivateKeyStructure privKey)
  171. {
  172. RSAParameters rp = new RSAParameters();
  173. rp.Modulus = privKey.Modulus.ToByteArrayUnsigned();
  174. rp.Exponent = privKey.PublicExponent.ToByteArrayUnsigned();
  175. rp.P = privKey.Prime1.ToByteArrayUnsigned();
  176. rp.Q = privKey.Prime2.ToByteArrayUnsigned();
  177. rp.D = ConvertRSAParametersField(privKey.PrivateExponent, rp.Modulus.Length);
  178. rp.DP = ConvertRSAParametersField(privKey.Exponent1, rp.P.Length);
  179. rp.DQ = ConvertRSAParametersField(privKey.Exponent2, rp.Q.Length);
  180. rp.InverseQ = ConvertRSAParametersField(privKey.Coefficient, rp.Q.Length);
  181. return rp;
  182. }
  183. // TODO Move functionality to more general class
  184. private static byte[] ConvertRSAParametersField(BigInteger n, int size)
  185. {
  186. byte[] bs = n.ToByteArrayUnsigned();
  187. if (bs.Length == size)
  188. return bs;
  189. if (bs.Length > size)
  190. throw new ArgumentException("Specified size too small", "size");
  191. byte[] padded = new byte[size];
  192. Array.Copy(bs, 0, padded, size - bs.Length, bs.Length);
  193. return padded;
  194. }
  195. private static RSA CreateRSAProvider(RSAParameters rp)
  196. {
  197. //CspParameters csp = new CspParameters();
  198. //csp.KeyContainerName = string.Format("BouncyCastle-{0}", Guid.NewGuid());
  199. //RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider(csp);
  200. //rsaCsp.ImportParameters(rp);
  201. var rsa = RSA.Create();
  202. rsa.ImportParameters(rp);
  203. return rsa;
  204. }
  205. }
  206. }
  207. #endif