فهرست منبع

add RSACryptoService tool

gsgundam 8 سال پیش
والد
کامیت
2bb8e021a4
2فایلهای تغییر یافته به همراه236 افزوده شده و 0 حذف شده
  1. 224 0
      Assets/Script/Tool/RSACryptoService.cs
  2. 12 0
      Assets/Script/Tool/RSACryptoService.cs.meta

+ 224 - 0
Assets/Script/Tool/RSACryptoService.cs

@@ -0,0 +1,224 @@
+using System;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+
+public class RSACryptoService
+{
+    private RSACryptoServiceProvider _privateKeyRsaProvider;
+    private RSACryptoServiceProvider _publicKeyRsaProvider;
+
+    public RSACryptoService(string privateKey, string publicKey = null)
+    {
+        if (!string.IsNullOrEmpty(privateKey))
+        {
+            _privateKeyRsaProvider = CreateRsaProviderFromPrivateKey(privateKey);
+        }
+
+        if (!string.IsNullOrEmpty(publicKey))
+        {
+            _publicKeyRsaProvider = CreateRsaProviderFromPublicKey(publicKey);
+        }
+    }
+
+    public string Decrypt(string cipherText)
+    {
+        if (_privateKeyRsaProvider == null)
+        {
+            throw new Exception("_privateKeyRsaProvider is null");
+        }
+        return Encoding.UTF8.GetString(_privateKeyRsaProvider.Decrypt(System.Convert.FromBase64String(cipherText), false));
+    }
+
+    public string Encrypt(string text)
+    {
+        if (_publicKeyRsaProvider == null)
+        {
+            throw new Exception("_publicKeyRsaProvider is null");
+        }
+        return Convert.ToBase64String(_publicKeyRsaProvider.Encrypt(Encoding.UTF8.GetBytes(text), false));
+    }
+
+    private RSACryptoServiceProvider CreateRsaProviderFromPrivateKey(string privateKey)
+    {
+        var privateKeyBits = System.Convert.FromBase64String(privateKey);
+
+        var RSA = new RSACryptoServiceProvider();
+        var RSAparams = new RSAParameters();
+
+        using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits)))
+        {
+            byte bt = 0;
+            ushort twobytes = 0;
+            twobytes = binr.ReadUInt16();
+            if (twobytes == 0x8130)
+                binr.ReadByte();
+            else if (twobytes == 0x8230)
+                binr.ReadInt16();
+            else
+                throw new Exception("Unexpected value read binr.ReadUInt16()");
+
+            twobytes = binr.ReadUInt16();
+            if (twobytes != 0x0102)
+                throw new Exception("Unexpected version");
+
+            bt = binr.ReadByte();
+            if (bt != 0x00)
+                throw new Exception("Unexpected value read binr.ReadByte()");
+
+            RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr));
+            RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr));
+            RSAparams.D = binr.ReadBytes(GetIntegerSize(binr));
+            RSAparams.P = binr.ReadBytes(GetIntegerSize(binr));
+            RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr));
+            RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr));
+            RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr));
+            RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr));
+        }
+
+        RSA.ImportParameters(RSAparams);
+        return RSA;
+    }
+
+    private int GetIntegerSize(BinaryReader binr)
+    {
+        byte bt = 0;
+        byte lowbyte = 0x00;
+        byte highbyte = 0x00;
+        int count = 0;
+        bt = binr.ReadByte();
+        if (bt != 0x02)
+            return 0;
+        bt = binr.ReadByte();
+
+        if (bt == 0x81)
+            count = binr.ReadByte();
+        else
+            if (bt == 0x82)
+        {
+            highbyte = binr.ReadByte();
+            lowbyte = binr.ReadByte();
+            byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
+            count = BitConverter.ToInt32(modint, 0);
+        }
+        else
+        {
+            count = bt;
+        }
+
+        while (binr.ReadByte() == 0x00)
+        {
+            count -= 1;
+        }
+        binr.BaseStream.Seek(-1, SeekOrigin.Current);
+        return count;
+    }
+
+    private RSACryptoServiceProvider CreateRsaProviderFromPublicKey(string publicKeyString)
+    {
+        // encoded OID sequence for  PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"
+        byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
+        byte[] x509key;
+        byte[] seq = new byte[15];
+        int x509size;
+
+        x509key = Convert.FromBase64String(publicKeyString);
+        x509size = x509key.Length;
+
+        // ---------  Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob  ------
+        using (MemoryStream mem = new MemoryStream(x509key))
+        {
+            using (BinaryReader binr = new BinaryReader(mem))  //wrap Memory Stream with BinaryReader for easy reading
+            {
+                byte bt = 0;
+                ushort twobytes = 0;
+
+                twobytes = binr.ReadUInt16();
+                if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
+                    binr.ReadByte();    //advance 1 byte
+                else if (twobytes == 0x8230)
+                    binr.ReadInt16();   //advance 2 bytes
+                else
+                    return null;
+
+                seq = binr.ReadBytes(15);       //read the Sequence OID
+                if (!CompareBytearrays(seq, SeqOID))    //make sure Sequence for OID is correct
+                    return null;
+
+                twobytes = binr.ReadUInt16();
+                if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81)
+                    binr.ReadByte();    //advance 1 byte
+                else if (twobytes == 0x8203)
+                    binr.ReadInt16();   //advance 2 bytes
+                else
+                    return null;
+
+                bt = binr.ReadByte();
+                if (bt != 0x00)     //expect null byte next
+                    return null;
+
+                twobytes = binr.ReadUInt16();
+                if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
+                    binr.ReadByte();    //advance 1 byte
+                else if (twobytes == 0x8230)
+                    binr.ReadInt16();   //advance 2 bytes
+                else
+                    return null;
+
+                twobytes = binr.ReadUInt16();
+                byte lowbyte = 0x00;
+                byte highbyte = 0x00;
+
+                if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81)
+                    lowbyte = binr.ReadByte();  // read next bytes which is bytes in modulus
+                else if (twobytes == 0x8202)
+                {
+                    highbyte = binr.ReadByte(); //advance 2 bytes
+                    lowbyte = binr.ReadByte();
+                }
+                else
+                    return null;
+                byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };   //reverse byte order since asn.1 key uses big endian order
+                int modsize = BitConverter.ToInt32(modint, 0);
+
+                int firstbyte = binr.PeekChar();
+                if (firstbyte == 0x00)
+                {   //if first byte (highest order) of modulus is zero, don't include it
+                    binr.ReadByte();    //skip this null byte
+                    modsize -= 1;   //reduce modulus buffer size by 1
+                }
+
+                byte[] modulus = binr.ReadBytes(modsize);   //read the modulus bytes
+
+                if (binr.ReadByte() != 0x02)            //expect an Integer for the exponent data
+                    return null;
+                int expbytes = (int)binr.ReadByte();        // should only need one byte for actual exponent data (for all useful values)
+                byte[] exponent = binr.ReadBytes(expbytes);
+
+                // ------- create RSACryptoServiceProvider instance and initialize with public key -----
+                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
+                RSAParameters RSAKeyInfo = new RSAParameters();
+                RSAKeyInfo.Modulus = modulus;
+                RSAKeyInfo.Exponent = exponent;
+                RSA.ImportParameters(RSAKeyInfo);
+
+                return RSA;
+            }
+
+        }
+    }
+
+    private bool CompareBytearrays(byte[] a, byte[] b)
+    {
+        if (a.Length != b.Length)
+            return false;
+        int i = 0;
+        foreach (byte c in a)
+        {
+            if (c != b[i])
+                return false;
+            i++;
+        }
+        return true;
+    }
+}

+ 12 - 0
Assets/Script/Tool/RSACryptoService.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: e0d7fe4713c937e41bf353f5aa18676b
+timeCreated: 1489757341
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: