messing with crypto
This commit is contained in:
parent
77830beaec
commit
3aed16024f
9 changed files with 553 additions and 1 deletions
49
src/BirdsiteLive.Cryptography/ASN1.cs
Normal file
49
src/BirdsiteLive.Cryptography/ASN1.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using Asn1;
|
||||
using Asn1Sequence = Asn1.Asn1Sequence;
|
||||
using Asn1Null = Asn1.Asn1Null;
|
||||
|
||||
namespace BirdsiteLive.Cryptography
|
||||
{
|
||||
public class ASN1
|
||||
{
|
||||
public static RSA ToRSA(byte[] data)
|
||||
{
|
||||
var node = Asn1Node.ReadNode(data);
|
||||
|
||||
var rsaSequence = Asn1Node.ReadNode((node.Nodes[1] as Asn1BitString).Data);
|
||||
|
||||
var modulus = (rsaSequence.Nodes[0] as Asn1Integer).Value;
|
||||
var exponent = (rsaSequence.Nodes[1] as Asn1Integer).Value;
|
||||
var prms = new RSAParameters { Modulus = modulus, Exponent = exponent };
|
||||
var rsa = RSA.Create();
|
||||
rsa.ImportParameters(prms);
|
||||
return rsa;
|
||||
}
|
||||
|
||||
public static byte[] FromRSA(RSA rsa)
|
||||
{
|
||||
var prms = rsa.ExportParameters(false);
|
||||
|
||||
var modulus = new Asn1Integer((new byte[] { 0x00 }.Concat(prms.Modulus)).ToArray());
|
||||
var exponent = new Asn1Integer(prms.Exponent);
|
||||
|
||||
var oidheader = new Asn1Sequence();
|
||||
oidheader.Nodes.Add(new Asn1ObjectIdentifier("1.2.840.113549.1.1.1"));
|
||||
oidheader.Nodes.Add(new Asn1Null());
|
||||
|
||||
var rsaSequence = new Asn1Sequence();
|
||||
rsaSequence.Nodes.Add(modulus);
|
||||
rsaSequence.Nodes.Add(exponent);
|
||||
|
||||
var bitString = new Asn1BitString(rsaSequence.GetBytes());
|
||||
|
||||
var result = new Asn1Sequence();
|
||||
result.Nodes.Add(oidheader);
|
||||
result.Nodes.Add(bitString);
|
||||
|
||||
return result.GetBytes();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,4 +4,10 @@
|
|||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Asn1" Version="1.0.9" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.8.6.7" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
175
src/BirdsiteLive.Cryptography/MagicKey.cs
Normal file
175
src/BirdsiteLive.Cryptography/MagicKey.cs
Normal file
|
@ -0,0 +1,175 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BirdsiteLive.Cryptography
|
||||
{
|
||||
public class MagicKey
|
||||
{
|
||||
//public class WebfingerLink
|
||||
//{
|
||||
// public string rel { get; set; }
|
||||
// public string type { get; set; }
|
||||
// public string href { get; set; }
|
||||
// public string template { get; set; }
|
||||
//}
|
||||
|
||||
//public class WebfingerResult
|
||||
//{
|
||||
// public string subject { get; set; }
|
||||
// public List<string> aliases { get; set; }
|
||||
// public List<WebfingerLink> links { get; set; }
|
||||
//}
|
||||
|
||||
private string[] _parts;
|
||||
private RSA _rsa;
|
||||
|
||||
private static byte[] _decodeBase64Url(string data)
|
||||
{
|
||||
return Convert.FromBase64String(data.Replace('-', '+').Replace('_', '/'));
|
||||
}
|
||||
|
||||
private static string _encodeBase64Url(byte[] data)
|
||||
{
|
||||
return Convert.ToBase64String(data).Replace('+', '-').Replace('/', '_');
|
||||
}
|
||||
|
||||
private class RSAKeyParms
|
||||
{
|
||||
public byte[] D;
|
||||
public byte[] DP;
|
||||
public byte[] DQ;
|
||||
public byte[] Exponent;
|
||||
public byte[] InverseQ;
|
||||
public byte[] Modulus;
|
||||
public byte[] P;
|
||||
public byte[] Q;
|
||||
|
||||
public static RSAKeyParms From(RSAParameters parms)
|
||||
{
|
||||
var a = new RSAKeyParms();
|
||||
a.D = parms.D;
|
||||
a.DP = parms.DP;
|
||||
a.DQ = parms.DQ;
|
||||
a.Exponent = parms.Exponent;
|
||||
a.InverseQ = parms.InverseQ;
|
||||
a.Modulus = parms.Modulus;
|
||||
a.P = parms.P;
|
||||
a.Q = parms.Q;
|
||||
return a;
|
||||
}
|
||||
|
||||
public RSAParameters Make()
|
||||
{
|
||||
var a = new RSAParameters();
|
||||
a.D = D;
|
||||
a.DP = DP;
|
||||
a.DQ = DQ;
|
||||
a.Exponent = Exponent;
|
||||
a.InverseQ = InverseQ;
|
||||
a.Modulus = Modulus;
|
||||
a.P = P;
|
||||
a.Q = Q;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
public MagicKey(string key)
|
||||
{
|
||||
if (key[0] == '{')
|
||||
{
|
||||
_rsa = RSA.Create();
|
||||
_rsa.ImportParameters(JsonConvert.DeserializeObject<RSAKeyParms>(key).Make());
|
||||
}
|
||||
else
|
||||
{
|
||||
_parts = key.Split('.');
|
||||
if (_parts[0] != "RSA") throw new Exception("Unknown magic key!");
|
||||
|
||||
var rsaParams = new RSAParameters();
|
||||
rsaParams.Modulus = _decodeBase64Url(_parts[1]);
|
||||
rsaParams.Exponent = _decodeBase64Url(_parts[2]);
|
||||
|
||||
_rsa = RSA.Create();
|
||||
_rsa.ImportParameters(rsaParams);
|
||||
}
|
||||
}
|
||||
|
||||
public static MagicKey Generate()
|
||||
{
|
||||
var rsa = RSA.Create();
|
||||
rsa.KeySize = 2048;
|
||||
|
||||
return new MagicKey(JsonConvert.SerializeObject(RSAKeyParms.From(rsa.ExportParameters(true))));
|
||||
}
|
||||
|
||||
//public static async Task<MagicKey> KeyForAuthor(ASObject obj)
|
||||
//{
|
||||
// var authorId = (string)obj["email"].FirstOrDefault()?.Primitive;
|
||||
// if (authorId == null)
|
||||
// {
|
||||
// authorId = obj["name"].FirstOrDefault()?.Primitive + "@" + new Uri(obj.Id).Host;
|
||||
// }
|
||||
|
||||
// var domain = authorId.Split('@')[1];
|
||||
// var hc = new HttpClient();
|
||||
// var wf = JsonConvert.DeserializeObject<WebfingerResult>(await hc.GetStringAsync($"https://{domain}/.well-known/webfinger?resource=acct:{Uri.EscapeDataString(authorId)}"));
|
||||
// var link = wf.links.FirstOrDefault(a => a.rel == "magic-public-key");
|
||||
// if (link == null) return null;
|
||||
|
||||
// if (!link.href.StartsWith("data:")) return null; // does this happen?
|
||||
|
||||
// return new MagicKey(link.href.Split(new char[] { ',' }, 2)[1]);
|
||||
//}
|
||||
|
||||
public byte[] BuildSignedData(string data, string dataType, string encoding, string algorithm)
|
||||
{
|
||||
var sig = data + "." + _encodeBase64Url(Encoding.UTF8.GetBytes(dataType)) + "." + _encodeBase64Url(Encoding.UTF8.GetBytes(encoding)) + "." + _encodeBase64Url(Encoding.UTF8.GetBytes(algorithm));
|
||||
return Encoding.UTF8.GetBytes(sig);
|
||||
}
|
||||
|
||||
public bool Verify(string signature, byte[] data)
|
||||
{
|
||||
return _rsa.VerifyData(data, _decodeBase64Url(signature), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
|
||||
}
|
||||
|
||||
public byte[] Sign(byte[] data)
|
||||
{
|
||||
return _rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
|
||||
}
|
||||
|
||||
public string AsPEM
|
||||
{
|
||||
get
|
||||
{
|
||||
var data = ASN1.FromRSA(_rsa);
|
||||
var baseData = Convert.ToBase64String(data);
|
||||
var builder = new StringBuilder(baseData);
|
||||
for (int i = 72; i < builder.Length; i += 73)
|
||||
builder.Insert(i, "\n");
|
||||
|
||||
builder.Insert(0, "-----BEGIN PUBLIC KEY-----\n");
|
||||
builder.Append("\n-----END PUBLIC KEY-----");
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public string PrivateKey
|
||||
{
|
||||
get { return JsonConvert.SerializeObject(RSAKeyParms.From(_rsa.ExportParameters(true))); }
|
||||
}
|
||||
|
||||
public string PublicKey
|
||||
{
|
||||
get
|
||||
{
|
||||
var parms = _rsa.ExportParameters(false);
|
||||
|
||||
return string.Join(".", "RSA", _encodeBase64Url(parms.Modulus), _encodeBase64Url(parms.Exponent));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
225
src/BirdsiteLive.Cryptography/RsaKeys.cs
Normal file
225
src/BirdsiteLive.Cryptography/RsaKeys.cs
Normal file
|
@ -0,0 +1,225 @@
|
|||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.OpenSsl;
|
||||
using Org.BouncyCastle.Security;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace MyProject.Data.Encryption
|
||||
{
|
||||
public class RSAKeys
|
||||
{
|
||||
/// <summary>
|
||||
/// Import OpenSSH PEM private key string into MS RSACryptoServiceProvider
|
||||
/// </summary>
|
||||
/// <param name="pem"></param>
|
||||
/// <returns></returns>
|
||||
public static RSACryptoServiceProvider ImportPrivateKey(string pem)
|
||||
{
|
||||
PemReader pr = new PemReader(new StringReader(pem));
|
||||
AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
|
||||
RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)KeyPair.Private);
|
||||
|
||||
RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams);
|
||||
csp.ImportParameters(rsaParams);
|
||||
return csp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Import OpenSSH PEM public key string into MS RSACryptoServiceProvider
|
||||
/// </summary>
|
||||
/// <param name="pem"></param>
|
||||
/// <returns></returns>
|
||||
public static RSACryptoServiceProvider ImportPublicKey(string pem)
|
||||
{
|
||||
PemReader pr = new PemReader(new StringReader(pem));
|
||||
AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject();
|
||||
RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey);
|
||||
|
||||
RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams);
|
||||
csp.ImportParameters(rsaParams);
|
||||
return csp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Export private (including public) key from MS RSACryptoServiceProvider into OpenSSH PEM string
|
||||
/// slightly modified from https://stackoverflow.com/a/23739932/2860309
|
||||
/// </summary>
|
||||
/// <param name="csp"></param>
|
||||
/// <returns></returns>
|
||||
public static string ExportPrivateKey(RSACryptoServiceProvider csp)
|
||||
{
|
||||
StringWriter outputStream = new StringWriter();
|
||||
if (csp.PublicOnly) throw new ArgumentException("CSP does not contain a private key", "csp");
|
||||
var parameters = csp.ExportParameters(true);
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
var writer = new BinaryWriter(stream);
|
||||
writer.Write((byte)0x30); // SEQUENCE
|
||||
using (var innerStream = new MemoryStream())
|
||||
{
|
||||
var innerWriter = new BinaryWriter(innerStream);
|
||||
EncodeIntegerBigEndian(innerWriter, new byte[] { 0x00 }); // Version
|
||||
EncodeIntegerBigEndian(innerWriter, parameters.Modulus);
|
||||
EncodeIntegerBigEndian(innerWriter, parameters.Exponent);
|
||||
EncodeIntegerBigEndian(innerWriter, parameters.D);
|
||||
EncodeIntegerBigEndian(innerWriter, parameters.P);
|
||||
EncodeIntegerBigEndian(innerWriter, parameters.Q);
|
||||
EncodeIntegerBigEndian(innerWriter, parameters.DP);
|
||||
EncodeIntegerBigEndian(innerWriter, parameters.DQ);
|
||||
EncodeIntegerBigEndian(innerWriter, parameters.InverseQ);
|
||||
var length = (int)innerStream.Length;
|
||||
EncodeLength(writer, length);
|
||||
writer.Write(innerStream.GetBuffer(), 0, length);
|
||||
}
|
||||
|
||||
var base64 = Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length).ToCharArray();
|
||||
// WriteLine terminates with \r\n, we want only \n
|
||||
outputStream.Write("-----BEGIN RSA PRIVATE KEY-----\n");
|
||||
// Output as Base64 with lines chopped at 64 characters
|
||||
for (var i = 0; i < base64.Length; i += 64)
|
||||
{
|
||||
outputStream.Write(base64, i, Math.Min(64, base64.Length - i));
|
||||
outputStream.Write("\n");
|
||||
}
|
||||
outputStream.Write("-----END RSA PRIVATE KEY-----");
|
||||
}
|
||||
|
||||
return outputStream.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Export public key from MS RSACryptoServiceProvider into OpenSSH PEM string
|
||||
/// slightly modified from https://stackoverflow.com/a/28407693
|
||||
/// </summary>
|
||||
/// <param name="csp"></param>
|
||||
/// <returns></returns>
|
||||
public static string ExportPublicKey(RSACryptoServiceProvider csp)
|
||||
{
|
||||
StringWriter outputStream = new StringWriter();
|
||||
var parameters = csp.ExportParameters(false);
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
var writer = new BinaryWriter(stream);
|
||||
writer.Write((byte)0x30); // SEQUENCE
|
||||
using (var innerStream = new MemoryStream())
|
||||
{
|
||||
var innerWriter = new BinaryWriter(innerStream);
|
||||
innerWriter.Write((byte)0x30); // SEQUENCE
|
||||
EncodeLength(innerWriter, 13);
|
||||
innerWriter.Write((byte)0x06); // OBJECT IDENTIFIER
|
||||
var rsaEncryptionOid = new byte[] { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
|
||||
EncodeLength(innerWriter, rsaEncryptionOid.Length);
|
||||
innerWriter.Write(rsaEncryptionOid);
|
||||
innerWriter.Write((byte)0x05); // NULL
|
||||
EncodeLength(innerWriter, 0);
|
||||
innerWriter.Write((byte)0x03); // BIT STRING
|
||||
using (var bitStringStream = new MemoryStream())
|
||||
{
|
||||
var bitStringWriter = new BinaryWriter(bitStringStream);
|
||||
bitStringWriter.Write((byte)0x00); // # of unused bits
|
||||
bitStringWriter.Write((byte)0x30); // SEQUENCE
|
||||
using (var paramsStream = new MemoryStream())
|
||||
{
|
||||
var paramsWriter = new BinaryWriter(paramsStream);
|
||||
EncodeIntegerBigEndian(paramsWriter, parameters.Modulus); // Modulus
|
||||
EncodeIntegerBigEndian(paramsWriter, parameters.Exponent); // Exponent
|
||||
var paramsLength = (int)paramsStream.Length;
|
||||
EncodeLength(bitStringWriter, paramsLength);
|
||||
bitStringWriter.Write(paramsStream.GetBuffer(), 0, paramsLength);
|
||||
}
|
||||
var bitStringLength = (int)bitStringStream.Length;
|
||||
EncodeLength(innerWriter, bitStringLength);
|
||||
innerWriter.Write(bitStringStream.GetBuffer(), 0, bitStringLength);
|
||||
}
|
||||
var length = (int)innerStream.Length;
|
||||
EncodeLength(writer, length);
|
||||
writer.Write(innerStream.GetBuffer(), 0, length);
|
||||
}
|
||||
|
||||
var base64 = Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length).ToCharArray();
|
||||
// WriteLine terminates with \r\n, we want only \n
|
||||
outputStream.Write("-----BEGIN PUBLIC KEY-----\n");
|
||||
for (var i = 0; i < base64.Length; i += 64)
|
||||
{
|
||||
outputStream.Write(base64, i, Math.Min(64, base64.Length - i));
|
||||
outputStream.Write("\n");
|
||||
}
|
||||
outputStream.Write("-----END PUBLIC KEY-----");
|
||||
}
|
||||
|
||||
return outputStream.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://stackoverflow.com/a/23739932/2860309
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="length"></param>
|
||||
private static void EncodeLength(BinaryWriter stream, int length)
|
||||
{
|
||||
if (length < 0) throw new ArgumentOutOfRangeException("length", "Length must be non-negative");
|
||||
if (length < 0x80)
|
||||
{
|
||||
// Short form
|
||||
stream.Write((byte)length);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Long form
|
||||
var temp = length;
|
||||
var bytesRequired = 0;
|
||||
while (temp > 0)
|
||||
{
|
||||
temp >>= 8;
|
||||
bytesRequired++;
|
||||
}
|
||||
stream.Write((byte)(bytesRequired | 0x80));
|
||||
for (var i = bytesRequired - 1; i >= 0; i--)
|
||||
{
|
||||
stream.Write((byte)(length >> (8 * i) & 0xff));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://stackoverflow.com/a/23739932/2860309
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="forceUnsigned"></param>
|
||||
private static void EncodeIntegerBigEndian(BinaryWriter stream, byte[] value, bool forceUnsigned = true)
|
||||
{
|
||||
stream.Write((byte)0x02); // INTEGER
|
||||
var prefixZeros = 0;
|
||||
for (var i = 0; i < value.Length; i++)
|
||||
{
|
||||
if (value[i] != 0) break;
|
||||
prefixZeros++;
|
||||
}
|
||||
if (value.Length - prefixZeros == 0)
|
||||
{
|
||||
EncodeLength(stream, 1);
|
||||
stream.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (forceUnsigned && value[prefixZeros] > 0x7f)
|
||||
{
|
||||
// Add a prefix zero to force unsigned if the MSB is 1
|
||||
EncodeLength(stream, value.Length - prefixZeros + 1);
|
||||
stream.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeLength(stream, value.Length - prefixZeros);
|
||||
}
|
||||
for (var i = prefixZeros; i < value.Length; i++)
|
||||
{
|
||||
stream.Write(value[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Domain", "Domain", "{4FEAD6
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BirdsiteLive.Twitter", "BirdsiteLive.Twitter\BirdsiteLive.Twitter.csproj", "{77C559D1-80A2-4B1C-A566-AE2D156944A4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdsiteLive.Common", "BirdsiteLive.Common\BirdsiteLive.Common.csproj", "{E64E7501-5DB8-4620-BA35-BA59FD746ABA}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BirdsiteLive.Common", "BirdsiteLive.Common\BirdsiteLive.Common.csproj", "{E64E7501-5DB8-4620-BA35-BA59FD746ABA}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{A32D3458-09D0-4E0A-BA4B-8C411B816B94}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdsiteLive.Cryptography.Tests", "Tests\BirdsiteLive.Cryptography.Tests\BirdsiteLive.Cryptography.Tests.csproj", "{155D46A4-2D05-47F2-8FFC-0B7C412A7652}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -35,6 +39,10 @@ Global
|
|||
{E64E7501-5DB8-4620-BA35-BA59FD746ABA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E64E7501-5DB8-4620-BA35-BA59FD746ABA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E64E7501-5DB8-4620-BA35-BA59FD746ABA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{155D46A4-2D05-47F2-8FFC-0B7C412A7652}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{155D46A4-2D05-47F2-8FFC-0B7C412A7652}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{155D46A4-2D05-47F2-8FFC-0B7C412A7652}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{155D46A4-2D05-47F2-8FFC-0B7C412A7652}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -43,6 +51,7 @@ Global
|
|||
{160AD138-4E29-4706-8546-9826B529E9B2} = {4FEAD6BC-3C8E-451A-8CA1-FF1AF47D26CC}
|
||||
{77C559D1-80A2-4B1C-A566-AE2D156944A4} = {4FEAD6BC-3C8E-451A-8CA1-FF1AF47D26CC}
|
||||
{E64E7501-5DB8-4620-BA35-BA59FD746ABA} = {4FEAD6BC-3C8E-451A-8CA1-FF1AF47D26CC}
|
||||
{155D46A4-2D05-47F2-8FFC-0B7C412A7652} = {A32D3458-09D0-4E0A-BA4B-8C411B816B94}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {69E8DCAD-4C37-4010-858F-5F94E6FBABCE}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\BirdsiteLive.Cryptography\BirdsiteLive.Cryptography.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
19
src/Tests/BirdsiteLive.Cryptography.Tests/MagicKeyTests.cs
Normal file
19
src/Tests/BirdsiteLive.Cryptography.Tests/MagicKeyTests.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace BirdsiteLive.Cryptography.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class MagicKeyTests
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task Test()
|
||||
{
|
||||
var g = MagicKey.Generate();
|
||||
|
||||
var magicKey = new MagicKey(g.PrivateKey);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace BirdsiteLive.Cryptography.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class RsaGeneratorTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestMethod1()
|
||||
{
|
||||
var rsaGen = new RsaGenerator();
|
||||
var rsa = rsaGen.GetRsa();
|
||||
}
|
||||
}
|
||||
}
|
34
src/Tests/BirdsiteLive.Cryptography.Tests/RsaKeysTests.cs
Normal file
34
src/Tests/BirdsiteLive.Cryptography.Tests/RsaKeysTests.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using System.Security.Cryptography;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MyProject.Data.Encryption;
|
||||
|
||||
namespace BirdsiteLive.Cryptography.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class RsaKeysTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestMethod1()
|
||||
{
|
||||
var rsa = RSA.Create();
|
||||
|
||||
var cspParams = new CspParameters();
|
||||
cspParams.ProviderType = 1; // PROV_RSA_FULL
|
||||
cspParams.Flags = CspProviderFlags.CreateEphemeralKey;
|
||||
var rsaProvider = new RSACryptoServiceProvider(2048, cspParams);
|
||||
|
||||
var rsaPublicKey = RSAKeys.ExportPublicKey(rsaProvider);
|
||||
var rsaPrivateKey = RSAKeys.ExportPrivateKey(rsaProvider);
|
||||
|
||||
//rsaProvider.
|
||||
|
||||
var pem = RSAKeys.ImportPublicKey(rsaPrivateKey);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestMethod2()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Reference in a new issue