PrivateKeyFactory.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using System.IO;
  6. using System.Text;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.CryptoPro;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.EdEC;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Oiw;
  11. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
  12. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Sec;
  13. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  14. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X9;
  15. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  16. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators;
  17. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  18. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  19. using BestHTTP.SecureProtocol.Org.BouncyCastle.Pkcs;
  20. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  21. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Security
  22. {
  23. public sealed class PrivateKeyFactory
  24. {
  25. private PrivateKeyFactory()
  26. {
  27. }
  28. public static AsymmetricKeyParameter CreateKey(
  29. byte[] privateKeyInfoData)
  30. {
  31. return CreateKey(
  32. PrivateKeyInfo.GetInstance(
  33. Asn1Object.FromByteArray(privateKeyInfoData)));
  34. }
  35. public static AsymmetricKeyParameter CreateKey(
  36. Stream inStr)
  37. {
  38. return CreateKey(
  39. PrivateKeyInfo.GetInstance(
  40. Asn1Object.FromStream(inStr)));
  41. }
  42. public static AsymmetricKeyParameter CreateKey(
  43. PrivateKeyInfo keyInfo)
  44. {
  45. AlgorithmIdentifier algID = keyInfo.PrivateKeyAlgorithm;
  46. DerObjectIdentifier algOid = algID.Algorithm;
  47. // TODO See RSAUtil.isRsaOid in Java build
  48. if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption)
  49. || algOid.Equals(X509ObjectIdentifiers.IdEARsa)
  50. || algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss)
  51. || algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
  52. {
  53. RsaPrivateKeyStructure keyStructure = RsaPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey());
  54. return new RsaPrivateCrtKeyParameters(
  55. keyStructure.Modulus,
  56. keyStructure.PublicExponent,
  57. keyStructure.PrivateExponent,
  58. keyStructure.Prime1,
  59. keyStructure.Prime2,
  60. keyStructure.Exponent1,
  61. keyStructure.Exponent2,
  62. keyStructure.Coefficient);
  63. }
  64. // TODO?
  65. // else if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber))
  66. else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
  67. {
  68. DHParameter para = new DHParameter(
  69. Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
  70. DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey();
  71. BigInteger lVal = para.L;
  72. int l = lVal == null ? 0 : lVal.IntValue;
  73. DHParameters dhParams = new DHParameters(para.P, para.G, null, l);
  74. return new DHPrivateKeyParameters(derX.Value, dhParams, algOid);
  75. }
  76. else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
  77. {
  78. ElGamalParameter para = new ElGamalParameter(
  79. Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
  80. DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey();
  81. return new ElGamalPrivateKeyParameters(
  82. derX.Value,
  83. new ElGamalParameters(para.P, para.G));
  84. }
  85. else if (algOid.Equals(X9ObjectIdentifiers.IdDsa))
  86. {
  87. DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey();
  88. Asn1Encodable ae = algID.Parameters;
  89. DsaParameters parameters = null;
  90. if (ae != null)
  91. {
  92. DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object());
  93. parameters = new DsaParameters(para.P, para.Q, para.G);
  94. }
  95. return new DsaPrivateKeyParameters(derX.Value, parameters);
  96. }
  97. else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
  98. {
  99. X962Parameters para = new X962Parameters(algID.Parameters.ToAsn1Object());
  100. X9ECParameters x9;
  101. if (para.IsNamedCurve)
  102. {
  103. x9 = ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)para.Parameters);
  104. }
  105. else
  106. {
  107. x9 = new X9ECParameters((Asn1Sequence)para.Parameters);
  108. }
  109. ECPrivateKeyStructure ec = ECPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey());
  110. BigInteger d = ec.GetKey();
  111. if (para.IsNamedCurve)
  112. {
  113. return new ECPrivateKeyParameters("EC", d, (DerObjectIdentifier)para.Parameters);
  114. }
  115. ECDomainParameters dParams = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());
  116. return new ECPrivateKeyParameters(d, dParams);
  117. }
  118. else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
  119. {
  120. Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
  121. Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
  122. ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);
  123. if (ecP == null)
  124. throw new ArgumentException("Unrecognized curve OID for GostR3410x2001 private key");
  125. Asn1Object privKey = keyInfo.ParsePrivateKey();
  126. ECPrivateKeyStructure ec;
  127. if (privKey is DerInteger)
  128. {
  129. ec = new ECPrivateKeyStructure(ecP.N.BitLength, ((DerInteger)privKey).PositiveValue);
  130. }
  131. else
  132. {
  133. ec = ECPrivateKeyStructure.GetInstance(privKey);
  134. }
  135. return new ECPrivateKeyParameters("ECGOST3410", ec.GetKey(), gostParams.PublicKeyParamSet);
  136. }
  137. else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
  138. {
  139. Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);
  140. Asn1Object privKey = keyInfo.ParsePrivateKey();
  141. BigInteger x;
  142. if (privKey is DerInteger)
  143. {
  144. x = DerInteger.GetInstance(privKey).PositiveValue;
  145. }
  146. else
  147. {
  148. x = new BigInteger(1, Arrays.Reverse(Asn1OctetString.GetInstance(privKey).GetOctets()));
  149. }
  150. return new Gost3410PrivateKeyParameters(x, gostParams.PublicKeyParamSet);
  151. }
  152. else if (algOid.Equals(EdECObjectIdentifiers.id_X25519))
  153. {
  154. return new X25519PrivateKeyParameters(GetRawKey(keyInfo, X25519PrivateKeyParameters.KeySize), 0);
  155. }
  156. else if (algOid.Equals(EdECObjectIdentifiers.id_X448))
  157. {
  158. return new X448PrivateKeyParameters(GetRawKey(keyInfo, X448PrivateKeyParameters.KeySize), 0);
  159. }
  160. else if (algOid.Equals(EdECObjectIdentifiers.id_Ed25519))
  161. {
  162. return new Ed25519PrivateKeyParameters(GetRawKey(keyInfo, Ed25519PrivateKeyParameters.KeySize), 0);
  163. }
  164. else if (algOid.Equals(EdECObjectIdentifiers.id_Ed448))
  165. {
  166. return new Ed448PrivateKeyParameters(GetRawKey(keyInfo, Ed448PrivateKeyParameters.KeySize), 0);
  167. }
  168. else
  169. {
  170. throw new SecurityUtilityException("algorithm identifier in private key not recognised");
  171. }
  172. }
  173. private static byte[] GetRawKey(PrivateKeyInfo keyInfo, int expectedSize)
  174. {
  175. byte[] result = Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctets();
  176. if (expectedSize != result.Length)
  177. throw new SecurityUtilityException("private key encoding has incorrect length");
  178. return result;
  179. }
  180. public static AsymmetricKeyParameter DecryptKey(
  181. char[] passPhrase,
  182. EncryptedPrivateKeyInfo encInfo)
  183. {
  184. return CreateKey(PrivateKeyInfoFactory.CreatePrivateKeyInfo(passPhrase, encInfo));
  185. }
  186. public static AsymmetricKeyParameter DecryptKey(
  187. char[] passPhrase,
  188. byte[] encryptedPrivateKeyInfoData)
  189. {
  190. return DecryptKey(passPhrase, Asn1Object.FromByteArray(encryptedPrivateKeyInfoData));
  191. }
  192. public static AsymmetricKeyParameter DecryptKey(
  193. char[] passPhrase,
  194. Stream encryptedPrivateKeyInfoStream)
  195. {
  196. return DecryptKey(passPhrase, Asn1Object.FromStream(encryptedPrivateKeyInfoStream));
  197. }
  198. private static AsymmetricKeyParameter DecryptKey(
  199. char[] passPhrase,
  200. Asn1Object asn1Object)
  201. {
  202. return DecryptKey(passPhrase, EncryptedPrivateKeyInfo.GetInstance(asn1Object));
  203. }
  204. public static byte[] EncryptKey(
  205. DerObjectIdentifier algorithm,
  206. char[] passPhrase,
  207. byte[] salt,
  208. int iterationCount,
  209. AsymmetricKeyParameter key)
  210. {
  211. return EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
  212. algorithm, passPhrase, salt, iterationCount, key).GetEncoded();
  213. }
  214. public static byte[] EncryptKey(
  215. string algorithm,
  216. char[] passPhrase,
  217. byte[] salt,
  218. int iterationCount,
  219. AsymmetricKeyParameter key)
  220. {
  221. return EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
  222. algorithm, passPhrase, salt, iterationCount, key).GetEncoded();
  223. }
  224. }
  225. }
  226. #pragma warning restore
  227. #endif