Só estou tentando reescrever esse código c# para python. O servidor envia a chave pública (módulo, expoente), precisa criptografá-la com preenchimento pkcs1.
using (TcpClient client = new TcpClient())
{
await client.ConnectAsync(ip, port);
using (NetworkStream stream = client.GetStream())
{
await App.SendCmdToServer(stream, "auth", this.Ver.ToString().Split('.', StringSplitOptions.None));
byte[] modulus = new byte[256];
int num2 = await stream.ReadAsync(modulus, 0, modulus.Length);
byte[] exponent = new byte[3];
int num3 = await stream.ReadAsync(exponent, 0, exponent.Length);
this.ServerRsa = RSA.Create();
this.ServerRsa.ImportParameters(new RSAParameters()
{
Modulus = modulus,
Exponent = exponent
});
using (MemoryStream data = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter((Stream) data))
{
writer.Write(string1);
writer.Write(string2);
await App.SendDataToServer(stream, this.ServerRsa.Encrypt(data.ToArray(), RSAEncryptionPadding.Pkcs1));
}
}
}
}
Tudo funciona bem, exceto o resultado criptografado pelo python. Eu tentei com rsa
e pycryptodome
, sem sorte alguma, o servidor retorna reject. Tentei algo assim ( rsa
)
server_rsa = rsa.newkeys(2048)[0]
server_rsa.n = int.from_bytes(modulus, byteorder='big')
server_rsa.e = int.from_bytes(exponent, byteorder='big')
data = (string1 + string2).encode()
encrypted_data = rsa.encrypt(data, server_rsa)
ou isto ( pycryptodome
)
pubkey = construct((int.from_bytes(modulus, 'big'), int.from_bytes(exponent, 'big')))
cipher = PKCS1_v1_5.new(pubkey)
encrypted_data = cipher.encrypt(data)
Existe alguma implementação especial do Python RSA que não funciona com C#, ou vice-versa?
Esta
PyCryptodome
é uma boa escolha para tarefas criptográficas em Python. O problema é com adata
formatação, você está concatenando as strings diretamente em Python e emBinaryWriter
C# escreve os comprimentos das strings como prefixos.Este código mostra como você pode fazer isso:
No código acima, codifiquei o comprimento das strings como big-endian unsigned int, mas como foi comentado por @Topaco, ele
BinaryWriter
codifica o prefixo de comprimento com LEB128 . Então, para replicar,BinaryWriter
você pode fazer isso:Eu usei o pacote leb128 que pode ser instalado com
pip install leb128
. Mas você pode criar uma função para fazer essa codificação