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>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</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>
|
</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
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BirdsiteLive.Twitter", "BirdsiteLive.Twitter\BirdsiteLive.Twitter.csproj", "{77C559D1-80A2-4B1C-A566-AE2D156944A4}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BirdsiteLive.Twitter", "BirdsiteLive.Twitter\BirdsiteLive.Twitter.csproj", "{77C559D1-80A2-4B1C-A566-AE2D156944A4}"
|
||||||
EndProject
|
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
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
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}.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.ActiveCfg = Release|Any CPU
|
||||||
{E64E7501-5DB8-4620-BA35-BA59FD746ABA}.Release|Any CPU.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -43,6 +51,7 @@ Global
|
||||||
{160AD138-4E29-4706-8546-9826B529E9B2} = {4FEAD6BC-3C8E-451A-8CA1-FF1AF47D26CC}
|
{160AD138-4E29-4706-8546-9826B529E9B2} = {4FEAD6BC-3C8E-451A-8CA1-FF1AF47D26CC}
|
||||||
{77C559D1-80A2-4B1C-A566-AE2D156944A4} = {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}
|
{E64E7501-5DB8-4620-BA35-BA59FD746ABA} = {4FEAD6BC-3C8E-451A-8CA1-FF1AF47D26CC}
|
||||||
|
{155D46A4-2D05-47F2-8FFC-0B7C412A7652} = {A32D3458-09D0-4E0A-BA4B-8C411B816B94}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {69E8DCAD-4C37-4010-858F-5F94E6FBABCE}
|
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()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue