116 lines
4.9 KiB
C#
116 lines
4.9 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using System.Threading;
|
|
using System.Windows;
|
|
|
|
namespace AnotherReplayReader.Utils
|
|
{
|
|
internal class VerifierPayload
|
|
{
|
|
public string Data { get; }
|
|
public string Signature { get; }
|
|
[JsonIgnore]
|
|
public Lazy<byte[]> ByteData { get; }
|
|
[JsonIgnore]
|
|
public Lazy<byte[]> ByteSignature { get; }
|
|
|
|
public VerifierPayload(string data, string signature)
|
|
{
|
|
Data = data;
|
|
Signature = signature;
|
|
ByteData = new(() => Convert.FromBase64String(Data),
|
|
LazyThreadSafetyMode.PublicationOnly);
|
|
ByteSignature = new(() => Convert.FromBase64String(Signature),
|
|
LazyThreadSafetyMode.PublicationOnly);
|
|
}
|
|
|
|
public static VerifierPayload FromBytes(byte[] data, byte[] signature)
|
|
{
|
|
return new(Convert.ToBase64String(data), Convert.ToBase64String(signature));
|
|
}
|
|
}
|
|
|
|
internal class Verifier
|
|
{
|
|
private const string _publicKey = @"<RSAKeyValue><Modulus>3vw5CoFRDFt2ri4jLDTu75cw1U/tCRjya7q8X/IdULaOJOYG8C+uqrF2Atb4ou+4SrmF+bvJM9cFsf3yO7XpeIDpkxD3KGbIEw+0JixTIIm+y5xlLKDDwbZHnYjJOBTt6JBn0yqwx7vY2UEZIcRU6wlOmUapnkpiaC2anNhSPqk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
|
|
|
|
public static bool Verify(VerifierPayload payload)
|
|
{
|
|
using var rsa = new RSACng();
|
|
rsa.FromXmlString(_publicKey);
|
|
return rsa.VerifyData(payload.ByteData.Value, payload.ByteSignature.Value, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
|
|
}
|
|
|
|
public static void Sign(object sample)
|
|
{
|
|
var fileName = Path.GetTempFileName();
|
|
try
|
|
{
|
|
var ea = Enumerable.Repeat<byte>(0xEA, 1024).ToArray();
|
|
const string splitter = "|DuplexBarrier|";
|
|
var isByteArray = false;
|
|
if (sample is string sampleText)
|
|
{
|
|
File.WriteAllText(fileName, $"输入私钥信息以及需要签名的数据,用 `{splitter}` 分开\r\n\r\n{sampleText}");
|
|
}
|
|
else if (sample is byte[] readyArray)
|
|
{
|
|
isByteArray = true;
|
|
File.WriteAllText(fileName, $"输入私钥信息以及需要签名的数据{splitter}{Convert.ToBase64String(readyArray)}{splitter}");
|
|
}
|
|
using (var process = Process.Start("notepad.exe", fileName))
|
|
{
|
|
process.WaitForExit();
|
|
}
|
|
var splitted = File.ReadAllText(fileName).Split(new[] { splitter }, StringSplitOptions.RemoveEmptyEntries);
|
|
File.WriteAllBytes(fileName, ea);
|
|
byte[] bytes;
|
|
byte[] signature;
|
|
|
|
using (var rsa = new RSACng())
|
|
{
|
|
rsa.FromXmlString(splitted[0]);
|
|
var text = splitted[1];
|
|
splitted = null;
|
|
GC.Collect();
|
|
MessageBox.Show(text, $"快来确认一下~");
|
|
bytes = isByteArray
|
|
? Convert.FromBase64String(text)
|
|
: Encoding.UTF8.GetBytes(text);
|
|
signature = rsa.SignData(bytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
|
|
}
|
|
GC.Collect();
|
|
var payload = VerifierPayload.FromBytes(bytes, signature);
|
|
var serialized = JsonSerializer.Serialize(payload, Network.CommonJsonOptions);
|
|
var choice = MessageBox.Show(serialized, "嗯哼", MessageBoxButton.YesNo);
|
|
while (choice == MessageBoxResult.Yes)
|
|
{
|
|
File.WriteAllText(fileName, serialized);
|
|
using (var process = Process.Start("notepad.exe", fileName))
|
|
{
|
|
process.WaitForExit();
|
|
}
|
|
using var rsa = new RSACng();
|
|
rsa.FromXmlString(_publicKey);
|
|
var checkContent = File.ReadAllText(fileName);
|
|
var check = JsonSerializer.Deserialize<VerifierPayload>(checkContent, Network.CommonJsonOptions) ?? new("", "");
|
|
var checkData = Convert.FromBase64String(check.Data);
|
|
var checkSignature = Convert.FromBase64String(check.Signature);
|
|
var verified = rsa.VerifyData(checkData, checkSignature, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
|
|
choice = MessageBox.Show($"结果:{verified}", "嗯哼", MessageBoxButton.YesNo);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
File.Delete(fileName);
|
|
}
|
|
}
|
|
}
|
|
}
|