Closed arnirichard closed 2 years ago
Hello. I could encrypt and decrypt data properly between C# and pointycastle. Following are my codes and outputs.
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Stream steam = Console.OpenStandardInput();
Console.SetIn(new StreamReader(steam, Encoding.Default, false, 5000));
RSACryptoServiceProvider algorithm = new RSACryptoServiceProvider(2048);
var param = algorithm.ExportParameters(false);
Console.WriteLine("Modulus in hex: " + BitConverter.ToString(param.Modulus).Replace("-", ""));
Console.WriteLine("Exponent in hex: " + BitConverter.ToString(param.Exponent).Replace("-", ""));
Console.Write("Input the encrypted data in base64: ");
string str = Console.ReadLine();
byte[] encryptData = Convert.FromBase64String(str);
byte[] decode = algorithm.Decrypt(encryptData, RSAEncryptionPadding.Pkcs1);
Console.WriteLine("Data in hex:" + BitConverter.ToString(decode).Replace("-", ""));
}
}
}
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
import 'package:convert/convert.dart';
import 'package:pointycastle/export.dart';
void main() {
final random = Random();
final data =
Uint8List.fromList(List<int>.generate(32, (_) => random.nextInt(256)));
print('Data (in hex): ' + hex.encode(data));
var m = BigInt.parse(
'Put the hex modulus here',
radix: 16,
);
var publickey = RSAPublicKey(m, BigInt.from(65537));
AsymmetricBlockCipher cipher = PKCS1Encoding(RSAEngine());
cipher.init(true, PublicKeyParameter<RSAPublicKey>(publickey));
var encryptedData = cipher.process(data);
print('The encrypted data (in base64): ' + base64.encode(encryptedData));
}
Modulus in hex: AAECF2246B2C4D5B9C505D72DEBD26FC62B7B18DAB42CA248B28B008C36D35945B33839997AEECD5176FFEC3C6B9BA8F8ABA2BB157C2927CB869A78DB605D8401CFA0AC4F813ABEAB583235EF266D9CD1A3A5A99D19BB314B5E1E6044F27CD4D6775167D0AA275C545193A9FA7863F5232FAFF6842561AFC32D56C1C4D28B03E32DB3C4F6B8C942CA68A6A957A47D1F9416D5E22BFF5A0E8BE51CD16FDEB755C2CFB01710E47380F56B9C07E6019D96300F21096E16E81C5B0396A45C3573AA79B7FB34F97260226E0AE5EF341585F85BE83D85378980457D7A197F3457918EAB7B11D8AE6172EF7A512CF59748E44B1C73A0504BC491B4074B2B6179D60E9FD
Exponent in hex: 010001
Input the encrypted data in base64: ZseP0ag5VdoShfSamDmUkys1Lo08oiPSbUdNr14LRDzrC5hn9xmyt0nlS0sJIRB8zzk4XEiYkX8utxDhhkTybReNZTqqQvTG/8fjilCZ2kHANYS4pJshhdrGTnOSmkL410LxklNF1PpKQHBS6E3nV5Z7ALrquN6U84AfVYpOvA5EB60c1rLg0V6Ef/MSKdMpaJoJwNNYIvLItbG2ngXLy2rBynlOvX6zdOxssAtLND1WKNFhL3AVSD718rLp8BkWrV2dVv0CS/tsxxkEEsrODGRuspS1DbNYiwcf+6ya/XhrTOFJyzN25eJCwY3slM1iO/sE6CM3o33YRSglawO8kg==
Data in hex:7D313D75AA2CB2A866CF3F40AC32AF9510E476799BEB29E5AF2C134CA2F65D46
Data (in hex): 7d313d75aa2cb2a866cf3f40ac32af9510e476799beb29e5af2c134ca2f65d46
The encrypted data (in base64): ZseP0ag5VdoShfSamDmUkys1Lo08oiPSbUdNr14LRDzrC5hn9xmyt0nlS0sJIRB8zzk4XEiYkX8utxDhhkTybReNZTqqQvTG/8fjilCZ2kHANYS4pJshhdrGTnOSmkL410LxklNF1PpKQHBS6E3nV5Z7ALrquN6U84AfVYpOvA5EB60c1rLg0V6Ef/MSKdMpaJoJwNNYIvLItbG2ngXLy2rBynlOvX6zdOxssAtLND1WKNFhL3AVSD718rLp8BkWrV2dVv0CS/tsxxkEEsrODGRuspS1DbNYiwcf+6ya/XhrTOFJyzN25eJCwY3slM1iO/sE6CM3o33YRSglawO8kg==
Thanks, I found out that the converter function readBytes
was incorrect. A correct implementation is below
static BigInt decodeBigInt(List<int> bytes) {
BigInt result = new BigInt.from(0);
for (int i = 0; i < bytes.length; i++) {
result += new BigInt.from(bytes[bytes.length - i - 1]) << (8 * i);
}
return result;
}
I am generating asymmetric key in C# and encrypting in Flutter using the public key, but decryption back fails in C#
in C#:
RSACryptoServiceProvider algorithm = new RSACryptoServiceProvider(2048);
var param = algorithm.ExportParameters(false);
byte[] modulus = param.Modulus;
byte[] exponent = param.Exponent;
modulus and exponent (65537) are used to create public key in Flutter, for encryption of list of 32 bytes (data), the resulting data is 256 bytes:
RSAPublicKey publickey = RSAPublicKey(readBytes(Uint8List.fromList(modulus)), readBytes(Uint8List.fromList(exponent));
AsymmetricBlockCipher cipher = PKCS1Encoding(RSAEngine());
cipher.init(true, PublicKeyParameter<RSAPublicKey>(publicKey));
Uint8List encryptedData = cipher.process(data)
Uint8List converted to BigInt using
static BigInt readBytes(Uint8List bytes) {
BigInt read(int start, int end) {
if (end - start <= 4) {
int result = 0;
for (int i = end - 1; i >= start; i--) {
result = result * 256 + bytes[i];
}
return new BigInt.from(result);
}
int mid = start + ((end - start) >> 1);
var result = read(start, mid) + read(mid, end) * (BigInt.one << ((mid - start) * 8));
return result;
}
return read(0, bytes.length);
}
In C# I try to decrypt the encrypted data (byte array) using the original RSACryptoServiceProvider (algorithm)
algorithm .Decrypt(encryptedData , RSAEncryptionPadding.Pkcs1);
which results in exception:
System.Security.Cryptography.CryptographicException HResult=0x80070057 Message=The parameter is incorrect.
Source=mscorlib StackTrace: at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) at System.Security.Cryptography.RSACryptoServiceProvider.DecryptKey(SafeKeyHandle pKeyContext, Byte[] pbEncryptedKey, Int32 cbEncryptedKey, Boolean fOAEP, ObjectHandleOnStack ohRetDecryptedKey) at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP) at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] data, RSAEncryptionPadding padding) at Logis.Utilities.Sockets.TPCv2.Internal.KeySet.Decrypt(RSACryptoServiceProvider aSK) in C:\Logis\TFS\Logis Tools\Logis.Utilities\Logis.Utilities\Sockets\TPCv2\Internal\KeySet.cs:line 40
I believe the problem is simple, but I can't figure it out. Can someone help?
I am using pointycastle: 3.4.0 and also tried pc_steelcrypt: 1.1.1