Open rickyazhari opened 5 years ago
@rickyazhari This is what i use for my pkcs1 encrypt, i'm using a C# based server implementation for decrypting and all is good. I'm passing in the modulus and exponent in as strings.
var text = "Your message here"
var pubKey = RSAPublicKey(BigInt.parse(modulus), BigInt.parse(exponent))
var cipher = PKCS1Encoding(RSAEngine());
cipher.init(true, PublicKeyParameter<RSAPublicKey>(pubKey));
Uint8List output = cipher.process(utf8.encode(text));
var base64EncodedText = base64Encode(output);
Give that a go and see if you get the same results.
hai @duncanhoggan thanks for advice. i already follow your code for encryption. unfortunately it's cannot decrypted as well. here's my code
RSAPublicKey pubkey = new RSAPublicKey(BigInt.parse(key,radix: 16), BigInt.parse("65537"));
var cipher = PKCS1Encoding(new RSAEngine());
cipher.init(true, PublicKeyParameter<RSAPublicKey>(pubkey));
var encryptText = cipher.process(Uint8List.fromList(plain.codeUnits));
List<String> hexes = "0123456789ABCDEF".split("");
StringBuffer buffer = new StringBuffer(2*encryptText.length);
for(int b in encryptText){
buffer.write(hexes[(b & 0xF0) >> 4]);
buffer.write(hexes[(b &0x0F)]);
}
return buffer.toString();
Really thanks, i still figure out where i miss
Hey, not sure what you plan is but you need the private and public pieces of the key to decrypt if you are using RSA.
Generally... message ---> encrypted using public key ---> transport ---> decrypted using private key ---> message
@duncanhoggan yah Generally such as you wrote in above. But i want just encryption process in client side and decryption in server side.
After some sample there is size different encryption result of native android encryption and flutter with pointy castle which is i've got 259 String length in flutter and 255 String length in native android. After that, flutter encryption result still failed to decrypt when native android is success one.
hi, i do RSA encryption with pointy castle and always failed to decrypted back.
btw, decrypt process is in different environment using PHP
here's my code :
BigInt modulus = BigInt.parse(key,radix: 16); BigInt exponent = BigInt.from(65537); RSAPublicKey pubKey = new RSAPublicKey(modulus, exponent); AsymmetricKeyParameter<RSAPublicKey> params = PublicKeyParameter(pubKey); //RSAEngine engine = new RSAEngine()..init(true, params); AsymmetricBlockCipher cipher = new AsymmetricBlockCipher("RSA/PKCS1")..init(true, params); Uint8List plainText = Uint8List.fromList(plain.codeUnits); Uint8List encryptText = cipher.process(plainText); List<String> hexes = "0123456789ABCDEF".split(""); StringBuffer buffer = new StringBuffer(2*encryptText.length); for(int b in encryptText){ buffer.write(hexes[(b & 0xF0) >> 4]); buffer.write(hexes[(b &0x0F)]); } return buffer.toString();
here's my flutter doctor
Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel beta, v0.9.4, on Mac OS X 10.14 18A391, locale en-ID) [✓] Android toolchain - develop for Android devices (Android SDK 27.0.3) [!] iOS toolchain - develop for iOS devices (Xcode 10.0) ! CocoaPods out of date (1.5.0 is recommended). CocoaPods is used to retrieve the iOS platform side's plugin code that responds to your plugin usage on the Dart side. Without resolving iOS dependencies with CocoaPods, plugins will not work on iOS. For more info, see https://flutter.io/platform-plugins To upgrade: brew upgrade cocoapods pod setup [✓] Android Studio (version 3.2) [!] VS Code (version 1.28.2) [✓] Connected devices (1 available)
is there something wrong in my encryption process ?
ok finally today i solve this problem. With sample test result
i run some test which is turn in to concluded with un-match length crypto text result. the result of crypto text using this method is 259. i use 2048 bit modulus and expect to get 256 crypto text length. and also in crypto text i found static value in front after i turn the result in to hex. ex :
plain text : pointycastle chiper text (HEX) : 256B360A8AF02823E084763A16727517B9741AEB562399B36743E995B92A3599C93FE4BEE64935CB670FBFCE8BB27372282D36A316AE750D72840CC0358C556F737EC11726F50F649C69B32A892366723DE8B59FF0F16ACBC57025CDCC6C498A58F17B66940F659C64A8172597A6CA53749F243EA68E3116F0560DD42EAAA75F9C2
plain text : password123 chiper text(HEX) : 256B8A2F63F393EC314E079029E170507BD5A4F66C6E042FC01E7889F14A200C25E8266122DDBF489BCDD505DE384E1F8061A554A3E041F4A4C78ED7AA515E866952B2522E0098842C7C99C61B20B575DDF3E1DC35696DCD471CB7C6D101D65303C7F04E5D00CCBEA9F1BF296A1C0A230016F20C544BE324724AF183401C1B9B7C0
plain text : github321 chiper text(HEX) : 256C60E4E493B4AC600FCD4579F06C55ABEFB4A7089F312BA1A29FA6FE3DA8A876D97142D754344AD73B5D7B1960C0B734A23AD876C7E87575AF25EB43E7461A398C082B69ABC14F0150A4BD53814AA928FEEE62AAD720E14E6372749C45C24039D98E30C028EBD3377780353425F713700556A36C896D873590AA7BF6E82B1388B
so i must remove 3 values in front of chiper text value and chiper text succesfully decrypted back.
thanks for cooperating this issue. please kindly check about that. we can close this issue and look for pointy-castle update
@rickyazhari firstly a side note you are using the older reflection based cipher initialisation. Try changing your init to the following.
AsymmetricBlockCipher cipher = PKCS1Encoding(RSAEngine());
cipher.init(true, PublicKeyParameter<RSAPublicKey>(pubKey));
The main issue here is your conversion from Uint8List
to hex String
.
I did the same conversion using the Hex package (shout out the @stevenroose for maintaining this one too)HEX.encode(encryptText);
and the output was correct.
String bufferToHex(Uint8List data){
List<String> hexLib = "0123456789ABCDEF".split("");
StringBuffer buffer = StringBuffer(2*data.length);
for(int dt in data){
buffer.write(hexLib[(dt & 0xF0) >> 4]);
buffer.write(hexLib[(dt &0x0F)]);
}
return buffer.toString();
}
I make hex conversion my self. it typically general conversion used to convert byte into hex string. I think that's not the main problem. But, I will try with hex library. and such as you suggested.
@rickyazhari I tested your code again and the hex conversion came out wrong...
var test1 = bufferToHex(Uint8List.fromList([0, 0, 0, 0]));
returns "800000000"
var test2 = bufferToHex(Uint8List.fromList([255, 255, 255, 255]));
returns "8FFFFFFFF"
Test it for yourself and you will come to the same conclusion. Feel free to close the issue when you discover this 👍
@duncanhoggan yah you right. I already test with hex library. I think it's already solve now. We can close this issue.
Can you share function for decrypting using private key ?
@lets-swapcode rather open a new issue as opposed to clouding this issue.
ar text = "Your message here" var pubKey = RSAPublicKey(BigInt.parse(modulus), BigInt.parse(exponent)) var cipher = PKCS1Encoding(RSAEngine()); cipher.init(true, PublicKeyParameter
(pubKey)); Uint8List output = cipher.process(utf8.encode(text)); var base64EncodedText = base64Encode(output);
I'd been battling this for weeks. Your solution worked like charm @duncanhoggan
hi C# Server :
public static string RsaEncrypt(string data, string pubkey) { RSAParameters ApublicKey; var pub = GetPublicKeyFromPemFile(pubkey); ApublicKey = pub.ExportParameters(false); RSAParameters result = new RSAParameters(); result.Modulus = ApublicKey.Modulus; result.Exponent = ApublicKey.Exponent; System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); byte[] DataToEncrypt = encoding.GetBytes(data); byte[] encryptedData;
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048))
{
RSA.ImportParameters(result);
encryptedData = RSA.Encrypt(DataToEncrypt, true);
}
return Convert.ToBase64String(encryptedData);
}
Dart Client :
AsymmetricKeyPair rsaGenerateKeyPair({int bitStrength = 2048}) {
var keyParams =
new RSAKeyGeneratorParameters(BigInt.parse('65537'), bitStrength, 12);
var secureRandom = new FortunaRandom();
var random = new Random.secure();
List
return k.generateKeyPair(); }
encodePublicKeyToPem(RSAPublicKey publicKey) { var algorithmSeq = new ASN1Sequence(); var algorithmAsn1Obj = new ASN1Object.fromBytes(Uint8List.fromList([0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1])); var paramsAsn1Obj = new ASN1Object.fromBytes(Uint8List.fromList([0x5, 0x0])); algorithmSeq.add(algorithmAsn1Obj); algorithmSeq.add(paramsAsn1Obj);
var publicKeySeq = new ASN1Sequence(); publicKeySeq.add(ASN1Integer(publicKey.modulus)); publicKeySeq.add(ASN1Integer(publicKey.exponent)); var publicKeySeqBitString = new ASN1BitString(Uint8List.fromList(publicKeySeq.encodedBytes)); var dataBase641 = base64.encode(publicKeySeq.encodedBytes); var dataBase642 = base64.encode(publicKeySeq.elements[1].encodedBytes); var topLevelSeq = new ASN1Sequence(); topLevelSeq.add(algorithmSeq); topLevelSeq.add(publicKeySeqBitString);
var dataBase64 = base64.encode(topLevelSeq.encodedBytes); return """-----BEGIN PUBLIC KEY-----\r\n$dataBase64\r\n-----END PUBLIC KEY-----"""; }
String decrypt(String cipherBase64, PublicKey pubkey,PrivateKey prvkry ) { final encrypter = Encrypter(RSA(publicKey: pubkey, privateKey: prvkry)); return encrypter.decrypt64(cipherBase64); }
this code not work true on dart, please help me
hi, i do RSA encryption with pointy castle and always failed to decrypted back.
btw, decrypt process is in different environment using PHP
here's my code :
here's my flutter doctor
is there something wrong in my encryption process ?