Brak opisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RSAPubKey.cs 3.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using LipingShare.LCLib.Asn1Processor;
  5. using System.Security.Cryptography;
  6. namespace UnityEngine.Purchasing.Security
  7. {
  8. internal class RSAKey
  9. {
  10. public RSACryptoServiceProvider rsa { get; private set; }
  11. public RSAKey(Asn1Node n)
  12. {
  13. rsa = ParseNode(n);
  14. }
  15. public RSAKey(byte[] data)
  16. {
  17. using (var stm = new System.IO.MemoryStream(data))
  18. {
  19. Asn1Parser parser = new Asn1Parser();
  20. parser.LoadData(stm);
  21. rsa = ParseNode(parser.RootNode);
  22. }
  23. }
  24. /**
  25. * Public verification of a message
  26. */
  27. public bool VerifySha1(byte[] message, byte[] signature)
  28. {
  29. var sha1hash = new SHA1Managed();
  30. var msgHash = sha1hash.ComputeHash(message);
  31. // The data is already hashed so we don't need to specify a hashing algorithm.
  32. return rsa.VerifyHash(msgHash, null, signature);
  33. }
  34. public bool VerifySha256(byte[] message, byte[] signature)
  35. {
  36. var sha256hash = new SHA256Managed();
  37. var msgHash = sha256hash.ComputeHash(message);
  38. // The data is already hashed so we don't need to specify a hashing algorithm.
  39. return rsa.VerifyHash(msgHash, CryptoConfig.MapNameToOID("SHA256"), signature);
  40. }
  41. /**
  42. * Parses an DER encoded RSA public key:
  43. * It will only try to get the mod and the exponent
  44. */
  45. private RSACryptoServiceProvider ParseNode(Asn1Node n)
  46. {
  47. if ((n.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.SEQUENCE &&
  48. n.ChildNodeCount == 2 &&
  49. (n.GetChildNode(0).Tag & Asn1Tag.TAG_MASK) == Asn1Tag.SEQUENCE &&
  50. (n.GetChildNode(0).GetChildNode(0).Tag & Asn1Tag.TAG_MASK) == Asn1Tag.OBJECT_IDENTIFIER &&
  51. n.GetChildNode(0).GetChildNode(0).GetDataStr(false) == "1.2.840.113549.1.1.1" &&
  52. (n.GetChildNode(1).Tag & Asn1Tag.TAG_MASK) == Asn1Tag.BIT_STRING)
  53. {
  54. var seq = n.GetChildNode(1).GetChildNode(0);
  55. if (seq.ChildNodeCount == 2)
  56. {
  57. byte[] data = seq.GetChildNode(0).Data;
  58. byte[] rawMod = new byte[data.Length - 1];
  59. System.Array.Copy(data, 1, rawMod, 0, data.Length - 1);
  60. var modulus = System.Convert.ToBase64String(rawMod);
  61. var exponent = System.Convert.ToBase64String(seq.GetChildNode(1).Data);
  62. var result = new RSACryptoServiceProvider();
  63. result.FromXmlString(ToXML(modulus, exponent));
  64. return result;
  65. }
  66. }
  67. throw new InvalidRSAData();
  68. }
  69. private string ToXML(string modulus, string exponent)
  70. {
  71. return "<RSAKeyValue><Modulus>" + modulus + "</Modulus>" +
  72. "<Exponent>" + exponent + "</Exponent></RSAKeyValue>";
  73. }
  74. }
  75. /// <summary>
  76. /// An IAP Security exception indicating some invalid data parsing an RSA node.
  77. /// </summary>
  78. public class InvalidRSAData : IAPSecurityException { }
  79. }