c# - ARC4 加密在服务器端无法正常工作
问题描述
我有一个 socket.io 客户端,它可以相互发送数据,其中加密基于 ARC4。
我尝试了多种不同的场景,但它一直无法解密任何东西,我不知道为什么。
班上:ARC4_New
public class ARC4_New
{
private int i;
private int j;
private byte[] bytes;
public const int POOLSIZE = 256;
public ARC4_New()
{
bytes = new byte[POOLSIZE];
}
public ARC4_New(byte[] key)
{
bytes = new byte[POOLSIZE];
this.Initialize(key);
}
public void Initialize(byte[] key)
{
this.i = 0;
this.j = 0;
for (i = 0; i < POOLSIZE; ++i)
{
this.bytes[i] = (byte)i;
}
for (i = 0; i < POOLSIZE; ++i)
{
j = (j + bytes[i] + key[i % key.Length]) & (POOLSIZE - 1);
this.Swap(i, j);
}
this.i = 0;
this.j = 0;
}
private void Swap(int a, int b)
{
byte t = this.bytes[a];
this.bytes[a] = this.bytes[b];
this.bytes[b] = t;
}
public byte Next()
{
this.i = ++this.i & (POOLSIZE - 1);
this.j = (this.j + this.bytes[i]) & (POOLSIZE - 1);
this.Swap(i, j);
return this.bytes[(this.bytes[i] + this.bytes[j]) & 255];
}
public void Encrypt(ref byte[] src)
{
for (int k = 0; k < src.Length; k++)
{
src[k] ^= this.Next();
}
}
public void Decrypt(ref byte[] src)
{
this.Encrypt(ref src);
}
}
public System.Numerics.BigInteger RandomInteger(int bitSize)
{
var integerData = new byte[bitSize / 8];
_numberGenerator.NextBytes(integerData);
integerData[integerData.Length - 1] &= 0x7f;
return new System.Numerics.BigInteger(integerData);
}
我的生成密钥的脚本:
System.Numerics.BigInteger DHPrivate = RandomInteger(256);
System.Numerics.BigInteger DHPrimal = RandomInteger(256);
System.Numerics.BigInteger DHGenerated = RandomInteger(256);
if (DHGenerated > DHPrimal)
{
System.Numerics.BigInteger tempG = DHGenerated;
DHGenerated= DHPrimal;
DHPrimal = tempG;
}
然后使用这些值生成一个公钥:
System.Numerics.BigInteger DHPublic = System.Numerics.BigInteger.ModPow(DHGenerated, DHPrivate, DHPrimal);
然后我加密这个密钥:
string pkey = EncryptY(CalculatePublic, DHPublic);
(以下加密的附加代码)
protected virtual string EncryptY(Func<System.Numerics.BigInteger, System.Numerics.BigInteger> calculator, System.Numerics.BigInteger value)
{
byte[] valueData = Encoding.UTF8.GetBytes(value.ToString());
valueData = PKCSPad(valueData);
Array.Reverse(valueData);
var paddedInteger = new System.Numerics.BigInteger(valueData);
System.Numerics.BigInteger calculatedInteger = calculator(paddedInteger);
byte[] paddedData = calculatedInteger.ToByteArray();
Array.Reverse(paddedData);
string encryptedValue = Utils.Converter.BytesToHexString(paddedData).ToLower();
return encryptedValue.StartsWith("00") ? encryptedValue.Substring(2) : encryptedValue;
}
protected virtual byte[] PKCSPad(byte[] data)
{
var buffer = new byte[128 - 1];
int dataStartPos = (buffer.Length - data.Length);
buffer[0] = (byte)Padding;
Buffer.BlockCopy(data, 0, buffer, dataStartPos, data.Length);
int paddingEndPos = (dataStartPos - 1);
bool isRandom = (Padding == PKCSPadding.RandomByte);
for (int i = 1; i < paddingEndPos; i++)
{
buffer[i] = (byte)(isRandom ?
_numberGenerator.Next(1, 256) : byte.MaxValue);
}
return buffer;
}
毕竟,我将字符串发送PKEY
到服务器。
解密字符串后,服务器得到公钥,例如:127458393
当我使用以下方式连接客户端和服务器时:127458393
喜欢:
BigInteger key = System.Numerics.BigInteger.Parse("127458393");
client = new ARC4_New(PrimalDing.ToByteArray());
我的客户发送一个字符串,如:
client.Encrypt(BYTE_HERE);
我的服务器读起来像:
client.Decrypt(BYTE_HERE);
但它失败了,并得到一个随机的不可读的字符串。
我在这里做错了什么?
解决方案
我设法解决了这个问题
出于某种原因,我的服务器曾经并且正在反转我在 ARC4 客户端中使用的字节。
所以我现在把它简单地反转为一个修补程序
System.Numerics.BigInteger temp = System.Numerics.BigInteger.Parse(textBox1.Text); client = new ARC4_New(temp.ToByteArray().Reverse().ToArray());
推荐阅读
- laravel - 如何在 Laravel 中使用 Getter Setter 方法?以及如何使用 Eloquent 模型添加字段?
- yii2 - 如何在表单中传递用户 ID
- angular - 在 onIdleStart 内部不调用 ajax
- c# - 如何在 ASP.NET Identity 中使用 OnModelCreating 添加管理员用户?
- c++ - 无法使用 OpenSSL 1.1.1 从 ClientHello 检索服务器名称 (SNI)
- hyperledger - 用于移动应用创建钱包和离线签名的 Hyperledger Fabric
- c# - Microsoft Teams 会议中的交互级别检查
- javascript - 从nodejs中的mongoDB查询返回数据
- angular - 数组的语法和格式
- java - SQLite 检查重复的用户名