PrivateKeyFactory.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  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.Rosstandart;
  13. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Sec;
  14. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  15. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X9;
  16. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  17. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators;
  18. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  19. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  20. using BestHTTP.SecureProtocol.Org.BouncyCastle.Pkcs;
  21. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  22. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Security
  23. {
  24. public sealed class PrivateKeyFactory
  25. {
  26. private PrivateKeyFactory()
  27. {
  28. }
  29. public static AsymmetricKeyParameter CreateKey(
  30. byte[] privateKeyInfoData)
  31. {
  32. return CreateKey(
  33. PrivateKeyInfo.GetInstance(
  34. Asn1Object.FromByteArray(privateKeyInfoData)));
  35. }
  36. public static AsymmetricKeyParameter CreateKey(
  37. Stream inStr)
  38. {
  39. return CreateKey(
  40. PrivateKeyInfo.GetInstance(
  41. Asn1Object.FromStream(inStr)));
  42. }
  43. public static AsymmetricKeyParameter CreateKey(
  44. PrivateKeyInfo keyInfo)
  45. {
  46. AlgorithmIdentifier algID = keyInfo.PrivateKeyAlgorithm;
  47. DerObjectIdentifier algOid = algID.Algorithm;
  48. // TODO See RSAUtil.isRsaOid in Java build
  49. if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption)
  50. || algOid.Equals(X509ObjectIdentifiers.IdEARsa)
  51. || algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss)
  52. || algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
  53. {
  54. RsaPrivateKeyStructure keyStructure = RsaPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey());
  55. return new RsaPrivateCrtKeyParameters(
  56. keyStructure.Modulus,
  57. keyStructure.PublicExponent,
  58. keyStructure.PrivateExponent,
  59. keyStructure.Prime1,
  60. keyStructure.Prime2,
  61. keyStructure.Exponent1,
  62. keyStructure.Exponent2,
  63. keyStructure.Coefficient);
  64. }
  65. // TODO?
  66. // else if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber))
  67. else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
  68. {
  69. DHParameter para = new DHParameter(
  70. Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
  71. DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey();
  72. BigInteger lVal = para.L;
  73. int l = lVal == null ? 0 : lVal.IntValue;
  74. DHParameters dhParams = new DHParameters(para.P, para.G, null, l);
  75. return new DHPrivateKeyParameters(derX.Value, dhParams, algOid);
  76. }
  77. else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
  78. {
  79. ElGamalParameter para = new ElGamalParameter(
  80. Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
  81. DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey();
  82. return new ElGamalPrivateKeyParameters(
  83. derX.Value,
  84. new ElGamalParameters(para.P, para.G));
  85. }
  86. else if (algOid.Equals(X9ObjectIdentifiers.IdDsa))
  87. {
  88. DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey();
  89. Asn1Encodable ae = algID.Parameters;
  90. DsaParameters parameters = null;
  91. if (ae != null)
  92. {
  93. DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object());
  94. parameters = new DsaParameters(para.P, para.Q, para.G);
  95. }
  96. return new DsaPrivateKeyParameters(derX.Value, parameters);
  97. }
  98. else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
  99. {
  100. X962Parameters para = X962Parameters.GetInstance(algID.Parameters.ToAsn1Object());
  101. X9ECParameters x9;
  102. if (para.IsNamedCurve)
  103. {
  104. x9 = ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)para.Parameters);
  105. }
  106. else
  107. {
  108. x9 = new X9ECParameters((Asn1Sequence)para.Parameters);
  109. }
  110. ECPrivateKeyStructure ec = ECPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey());
  111. BigInteger d = ec.GetKey();
  112. if (para.IsNamedCurve)
  113. {
  114. return new ECPrivateKeyParameters("EC", d, (DerObjectIdentifier)para.Parameters);
  115. }
  116. ECDomainParameters dParams = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());
  117. return new ECPrivateKeyParameters(d, dParams);
  118. }
  119. else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
  120. {
  121. Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(
  122. algID.Parameters.ToAsn1Object());
  123. X9ECParameters ecP = ECGost3410NamedCurves.GetByOidX9(gostParams.PublicKeyParamSet);
  124. if (ecP == null)
  125. throw new ArgumentException("Unrecognized curve OID for GostR3410x2001 private key");
  126. Asn1Object privKey = keyInfo.ParsePrivateKey();
  127. ECPrivateKeyStructure ec;
  128. if (privKey is DerInteger)
  129. {
  130. ec = new ECPrivateKeyStructure(ecP.N.BitLength, ((DerInteger)privKey).PositiveValue);
  131. }
  132. else
  133. {
  134. ec = ECPrivateKeyStructure.GetInstance(privKey);
  135. }
  136. return new ECPrivateKeyParameters("ECGOST3410", ec.GetKey(), gostParams.PublicKeyParamSet);
  137. }
  138. else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
  139. {
  140. Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);
  141. Asn1Object privKey = keyInfo.ParsePrivateKey();
  142. BigInteger x;
  143. if (privKey is DerInteger)
  144. {
  145. x = DerInteger.GetInstance(privKey).PositiveValue;
  146. }
  147. else
  148. {
  149. x = new BigInteger(1, Arrays.Reverse(Asn1OctetString.GetInstance(privKey).GetOctets()));
  150. }
  151. return new Gost3410PrivateKeyParameters(x, gostParams.PublicKeyParamSet);
  152. }
  153. else if (algOid.Equals(EdECObjectIdentifiers.id_X25519))
  154. {
  155. return new X25519PrivateKeyParameters(GetRawKey(keyInfo));
  156. }
  157. else if (algOid.Equals(EdECObjectIdentifiers.id_X448))
  158. {
  159. return new X448PrivateKeyParameters(GetRawKey(keyInfo));
  160. }
  161. else if (algOid.Equals(EdECObjectIdentifiers.id_Ed25519))
  162. {
  163. return new Ed25519PrivateKeyParameters(GetRawKey(keyInfo));
  164. }
  165. else if (algOid.Equals(EdECObjectIdentifiers.id_Ed448))
  166. {
  167. return new Ed448PrivateKeyParameters(GetRawKey(keyInfo));
  168. }
  169. else if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512)
  170. || algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256))
  171. {
  172. Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(keyInfo.PrivateKeyAlgorithm.Parameters);
  173. ECGost3410Parameters ecSpec;
  174. BigInteger d;
  175. Asn1Object p = keyInfo.PrivateKeyAlgorithm.Parameters.ToAsn1Object();
  176. if (p is Asn1Sequence && (Asn1Sequence.GetInstance(p).Count == 2 || Asn1Sequence.GetInstance(p).Count == 3))
  177. {
  178. X9ECParameters ecP = ECGost3410NamedCurves.GetByOidX9(gostParams.PublicKeyParamSet);
  179. ecSpec = new ECGost3410Parameters(
  180. new ECNamedDomainParameters(
  181. gostParams.PublicKeyParamSet, ecP),
  182. gostParams.PublicKeyParamSet,
  183. gostParams.DigestParamSet,
  184. gostParams.EncryptionParamSet);
  185. Asn1OctetString privEnc = keyInfo.PrivateKeyData;
  186. if (privEnc.GetOctets().Length == 32 || privEnc.GetOctets().Length == 64)
  187. {
  188. byte[] dVal = Arrays.Reverse(privEnc.GetOctets());
  189. d = new BigInteger(1, dVal);
  190. }
  191. else
  192. {
  193. Asn1Encodable privKey = keyInfo.ParsePrivateKey();
  194. if (privKey is DerInteger)
  195. {
  196. d = DerInteger.GetInstance(privKey).PositiveValue;
  197. }
  198. else
  199. {
  200. byte[] dVal = Arrays.Reverse(Asn1OctetString.GetInstance(privKey).GetOctets());
  201. d = new BigInteger(1, dVal);
  202. }
  203. }
  204. }
  205. else
  206. {
  207. X962Parameters parameters = X962Parameters.GetInstance(keyInfo.PrivateKeyAlgorithm.Parameters);
  208. if (parameters.IsNamedCurve)
  209. {
  210. DerObjectIdentifier oid = DerObjectIdentifier.GetInstance(parameters.Parameters);
  211. X9ECParameters ecP = ECNamedCurveTable.GetByOid(oid);
  212. ecSpec = new ECGost3410Parameters(new ECNamedDomainParameters(oid, ecP),
  213. gostParams.PublicKeyParamSet, gostParams.DigestParamSet,
  214. gostParams.EncryptionParamSet);
  215. }
  216. else if (parameters.IsImplicitlyCA)
  217. {
  218. ecSpec = null;
  219. }
  220. else
  221. {
  222. X9ECParameters ecP = X9ECParameters.GetInstance(parameters.Parameters);
  223. ecSpec = new ECGost3410Parameters(new ECNamedDomainParameters(algOid, ecP),
  224. gostParams.PublicKeyParamSet, gostParams.DigestParamSet,
  225. gostParams.EncryptionParamSet);
  226. }
  227. Asn1Encodable privKey = keyInfo.ParsePrivateKey();
  228. if (privKey is DerInteger)
  229. {
  230. DerInteger derD = DerInteger.GetInstance(privKey);
  231. d = derD.Value;
  232. }
  233. else
  234. {
  235. ECPrivateKeyStructure ec = ECPrivateKeyStructure.GetInstance(privKey);
  236. d = ec.GetKey();
  237. }
  238. }
  239. return new ECPrivateKeyParameters(
  240. d,
  241. new ECGost3410Parameters(
  242. ecSpec,
  243. gostParams.PublicKeyParamSet,
  244. gostParams.DigestParamSet,
  245. gostParams.EncryptionParamSet));
  246. }
  247. else
  248. {
  249. throw new SecurityUtilityException("algorithm identifier in private key not recognised");
  250. }
  251. }
  252. private static byte[] GetRawKey(PrivateKeyInfo keyInfo)
  253. {
  254. return Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctets();
  255. }
  256. public static AsymmetricKeyParameter DecryptKey(
  257. char[] passPhrase,
  258. EncryptedPrivateKeyInfo encInfo)
  259. {
  260. return CreateKey(PrivateKeyInfoFactory.CreatePrivateKeyInfo(passPhrase, encInfo));
  261. }
  262. public static AsymmetricKeyParameter DecryptKey(
  263. char[] passPhrase,
  264. byte[] encryptedPrivateKeyInfoData)
  265. {
  266. return DecryptKey(passPhrase, Asn1Object.FromByteArray(encryptedPrivateKeyInfoData));
  267. }
  268. public static AsymmetricKeyParameter DecryptKey(
  269. char[] passPhrase,
  270. Stream encryptedPrivateKeyInfoStream)
  271. {
  272. return DecryptKey(passPhrase, Asn1Object.FromStream(encryptedPrivateKeyInfoStream));
  273. }
  274. private static AsymmetricKeyParameter DecryptKey(
  275. char[] passPhrase,
  276. Asn1Object asn1Object)
  277. {
  278. return DecryptKey(passPhrase, EncryptedPrivateKeyInfo.GetInstance(asn1Object));
  279. }
  280. public static byte[] EncryptKey(
  281. DerObjectIdentifier algorithm,
  282. char[] passPhrase,
  283. byte[] salt,
  284. int iterationCount,
  285. AsymmetricKeyParameter key)
  286. {
  287. return EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
  288. algorithm, passPhrase, salt, iterationCount, key).GetEncoded();
  289. }
  290. public static byte[] EncryptKey(
  291. string algorithm,
  292. char[] passPhrase,
  293. byte[] salt,
  294. int iterationCount,
  295. AsymmetricKeyParameter key)
  296. {
  297. return EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
  298. algorithm, passPhrase, salt, iterationCount, key).GetEncoded();
  299. }
  300. }
  301. }
  302. #pragma warning restore
  303. #endif