Open stevenroose opened 6 years ago
This bug is still exist? In my code, method generateKeyPair() don't return any value? Anyone had the same problem?
var parameters = RSAKeyGeneratorParameters(BigInt.from(65537), 1024, 5);
var secureRandom = new FortunaRandom();
var random = new Random.secure();
List<int> seeds = [];
for (int i = 0; i < 32; i++) {
seeds.add(random.nextInt(255));
}
secureRandom.seed(new KeyParameter(new Uint8List.fromList(seeds)));
var params = new ParametersWithRandom(parameters, secureRandom);
rsaKeyGenerator.init(params);
// This block never return value
var keyPair = rsaKeyGenerator.generateKeyPair();
Using FixedSecureRandom have the same effect.
I used my code in flutter.
Ok i repair this bug.
Fixed implementation of method generateKeyPair, please update this method or give me right to repository push.
The was with bad usage BigInit.
For example:
if (e.gcd(q - BigInt.one) == 1) {
break;
}
This "if" was never "true" because "BigInt.gcd()" return "BigInt" not "int", so "break" never happen and method start infinity loop. I change it to:
if (e.gcd(q - BigInt.one) == BigInt.one) {
break;
}
Full fixed method:
AsymmetricKeyPair generateKeyPair() {
var p, q, n, e;
// p and q values should have a length of half the strength in bits
var strength = _params.bitStrength;
var pbitlength = (strength + 1) ~/ 2;
var qbitlength = strength - pbitlength;
var mindiffbits = strength ~/ 3;
e = _params.publicExponent;
// TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes)
// (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")
// generate p, prime and (p-1) relatively prime to e
for ( ; ; ) {
p = generateProbablePrime(pbitlength, 1, _random);
if (p % e == BigInt.one) {
continue;
}
if (!_isProbablePrime(p, _params.certainty)) {
continue;
}
if (e.gcd(p - BigInt.one) == BigInt.one) {
break;
}
}
// generate a modulus of the required length
for ( ; ; ) {
// generate q, prime and (q-1) relatively prime to e, and not equal to p
for ( ; ; ) {
q = generateProbablePrime(qbitlength, 1, _random);
if ((q - p).abs().bitLength < mindiffbits) {
continue;
}
if (q.modInverse(e) == BigInt.one) {
continue;
}
if (!_isProbablePrime(q, _params.certainty)) {
continue;
}
if (e.gcd(q - BigInt.one) == BigInt.one) {
break;
}
}
// calculate the modulus
n = (p * q);
if (n.bitLength == _params.bitStrength) {
break;
}
// if we get here our primes aren't big enough, make the largest of the two p and try again
p = (p.compareTo(q) > 0) ? p : q;
}
// Swap p and q if necessary
if (p < q) {
var swap = p;
p = q;
q = swap;
}
// calculate the private exponent
var pSub1 = (p - BigInt.one);
var qSub1 = (q - BigInt.one);
var phi = (pSub1 * qSub1);
var d = e.modInverse(phi);
return new AsymmetricKeyPair(new RSAPublicKey(n, e), new RSAPrivateKey(n, d, p, q));
}
@krzaklus I tried your method, and now the generateKeyPair() is not stuck anymore :) Thanks!
However, when i initialize the RSAEngine with the public key, it gives me the following error:
type 'RSAPublicKey' is not a subtype of type 'Null'
The code I have is the following:
RSAEngine cipherBlock = RSAEngine()
..init(true, new PublicKeyParameter(keys.publicKey));
and he throws the exception in the constructor of the PublicKeyParameter.
Is this a problem a consequence of the changes you made, or is it something else?
I think is something else, I didn't any changes on types, if you want solve
this you must used this code below (keyParametersPublic must by cast to
type AsymmetricKeyParameter
AsymmetricKeyParameter
var cipher = new RSAEngine()..init(true, keyParametersPublic);
My full method:
static String encrypt(String plainText, RSAPublicKey publicKey) {
try {
AsymmetricKeyParameter
var cipher = new RSAEngine()..init(true, keyParametersPublic);
var cipherText = cipher.process(new Uint8List.fromList(plainText.codeUnits));
return base64.encode(cipherText); } catch (e) { print(e.toString()); return null; } }
Encrypt and Decrypt works well, but I stucked on sign data with rsa, my code.
var rsaSigner = RSASigner(new SHA256Digest(), "0609608648016503040201");
AsymmetricBlockCipher _rsa = PKCS1Encoding(RSAEngine());
AsymmetricKeyParameter
rsaSigner.init(true, keyParametersPrivate);
method init throw me
EXCEPTION: Bad state: Reflectable has not been initialized. Did you forget to add the main file to the reflectable transformer's entry_points in pubspec.yaml?
I compile my code on flutter, and I dont now whot shoul I do next:/
czw., 28 cze 2018 o 20:32 José Carlos Coutinho notifications@github.com napisał(a):
@krzaklus https://github.com/krzaklus I tried your method, and now the generateKeyPair() is not stuck anymore :) Thanks! However, when i initialize the RSAEngine with the public key, it gives me the following error: type 'RSAPublicKey' is not a subtype of type 'Null'
The code I have is the following:
RSAEngine cipherBlock = RSAEngine() ..init(true, new PublicKeyParameter(keys.publicKey));
and he throws the exception in the constructor of the PublicKeyParameter.
Is this a problem a consequence of the changes you made, or is it something else?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/PointyCastle/pointycastle/issues/127#issuecomment-401131166, or mute the thread https://github.com/notifications/unsubscribe-auth/ANV0TmqmiP7UugFikXmayWGqAuwjBtygks5uBSFSgaJpZM4UQZpZ .
I think property final AsymmetricBlockCipher _rsa = PKCS1Encoding(RSAEngine());
from lib class class RSASigner implements Signer
need reflection to build, thats why I have that error, but I dont know how to overide this, do you have any sugestion?
czw., 28 cze 2018 o 20:58 Krzysztof krzaklus@gmail.com napisał(a):
I think is something else, I didn't any changes on types, if you want solve this you must used this code below (keyParametersPublic must by cast to type AsymmetricKeyParameter
): AsymmetricKeyParameter
keyParametersPublic = new PublicKeyParameter(publicKey); var cipher = new RSAEngine()..init(true, keyParametersPublic);
My full method:
static String encrypt(String plainText, RSAPublicKey publicKey) { try { AsymmetricKeyParameter
keyParametersPublic = new PublicKeyParameter(publicKey); var cipher = new RSAEngine()..init(true, keyParametersPublic);
var cipherText = cipher.process(new Uint8List.fromList(plainText.codeUnits));
return base64.encode(cipherText); } catch (e) { print(e.toString()); return null; } }
Encrypt and Decrypt works well, but I stucked on sign data with rsa, my code.
var rsaSigner = RSASigner(new SHA256Digest(), "0609608648016503040201");
AsymmetricBlockCipher _rsa = PKCS1Encoding(RSAEngine()); AsymmetricKeyParameter
keyParametersPrivate = new PrivateKeyParameter(keyPair.privateKey); rsaSigner.init(true, keyParametersPrivate);
method init throw me
EXCEPTION: Bad state: Reflectable has not been initialized. Did you forget to add the main file to the reflectable transformer's entry_points in pubspec.yaml?
I compile my code on flutter, and I dont now whot shoul I do next:/
czw., 28 cze 2018 o 20:32 José Carlos Coutinho notifications@github.com napisał(a):
@krzaklus https://github.com/krzaklus I tried your method, and now the generateKeyPair() is not stuck anymore :) Thanks! However, when i initialize the RSAEngine with the public key, it gives me the following error: type 'RSAPublicKey' is not a subtype of type 'Null'
The code I have is the following:
RSAEngine cipherBlock = RSAEngine() ..init(true, new PublicKeyParameter(keys.publicKey));
and he throws the exception in the constructor of the PublicKeyParameter.
Is this a problem a consequence of the changes you made, or is it something else?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/PointyCastle/pointycastle/issues/127#issuecomment-401131166, or mute the thread https://github.com/notifications/unsubscribe-auth/ANV0TmqmiP7UugFikXmayWGqAuwjBtygks5uBSFSgaJpZM4UQZpZ .
I am still a beginner, but I believe it is a problem when the program reaches the SecureRandom
constructor.
In pkcs1.dart, it crashes in the init
method, when the cypher parameters are not an instance of ParametersWithRandom
.
The program enters the "else", and tries to create the instance of SecureRandom
without the algorithmName
argument, which I believe its the cause of the error.
// pkcs1.dart
void init(bool forEncryption, CipherParameters params) {
AsymmetricKeyParameter akparams;
if (params is ParametersWithRandom) {
ParametersWithRandom paramswr = params;
_random = paramswr.random;
akparams = paramswr.parameters;
} else {
_random = new SecureRandom(); //Crashes here
akparams = params;
}
_engine.init(forEncryption, akparams);
_forPrivateKey = (akparams.key is PrivateKey);
_forEncryption = forEncryption;
}
Maybe using a default algorithm name in SecureRandom constructor, instead of "" would solve the problem? (I don't know almost anything about the secure random number generators, so I don't know the names of the possible algorithms :cry: )
// secure_random.dart
factory SecureRandom([String algorithmName = "<algorithmName>"]) =>
registry.create(SecureRandom, algorithmName) as SecureRandom;
Please, update 'generateKeyPair' to:
AsymmetricKeyPair<RSAPublicKey, RSAPrivateKey> generateKeyPair() {...}
Otherwise I can not do this:
print(keyPair.publicKey.modulus); print(keyPair.publicKey.exponent);
I can not use the method SecureRandom()
in Flutter - it crashes.
flutter: Another exception was thrown: NoSuchMethodError: The method '[]' was called on null.
@proteye for that specific issue you need to specify a random algorithm. new SecureRandom("Fortuna")
with registry or new FortunaRandom()
without registry.
As for the prior comments: are those still relevant? If so, could someone make a PR perhaps?
@stevenroose thank you. I realized this as follows: https://gist.github.com/proteye/982d9991922276ccfb011dfc55443d74
I fixed the code as @krzaklus and sent PR. https://github.com/PointyCastle/pointycastle/pull/135
I'm trying to make RSAEngine to work and I am facing the same issue:
type 'RSAPublicKey' is not a subtype of type 'Null'
I referenced the RC version of the pointycastle library in my pubspec.yaml:
pointycastle: ^1.0.0-rc4
The exception is thrown in the following line of code:
var cipher = new RSAEngine()..init( true, new PublicKeyParameter(keyPair.publicKey));
I'm struggling for this thing to work in flutter and so far there is no hope nor there are relevant resources out there that I can find. Is this fixed or there is another workaround?
P.S. I have a simple method just to test the functionality:
@protected
void testGenerateRSA() {
print('Generating RSA keys...');
var keyParams = new RSAKeyGeneratorParameters(new BigInt.from(65537), 2048, 5);
var secureRandom = new SecureRandom("Fortuna"); // new FortunaRandom();
var random = new Random.secure();
const int seedLength = 32;
const int randomMax = 255;
final Uint8List uint8list = new Uint8List(seedLength);
for (int i=0; i < seedLength; i++) {
uint8list[i] = random.nextInt(randomMax);
}
final KeyParameter keyParameter = new KeyParameter(uint8list);
secureRandom.seed(keyParameter);
var rngParams = new ParametersWithRandom(keyParams, secureRandom);
var k = new RSAKeyGenerator();
k.init(rngParams);
var keyPair = k.generateKeyPair();
var cipher = new RSAEngine()..init( true, new PublicKeyParameter(keyPair.publicKey));
var cipherText = cipher.process(new Uint8List.fromList("Hello World".codeUnits));
print("Encrypted: ${new String.fromCharCodes(cipherText)}");
cipher.init( false, new PrivateKeyParameter(keyPair.privateKey));
var decrypted = cipher.process(cipherText);
print("Decrypted: ${new String.fromCharCodes(decrypted)}");
}
I am also see this issue above except with a private key and receive type 'RSAPrivateKey' is not a subtype of type 'Null'
Anyone else seeing this issue?
@mslavkovski @coylums
You are not providing the type in the generic classes in two of your lines where you create PublicKeyParameter and PrivateKeyParameter. I suspect the underlying code is casting to a T which is undefined, so you are getting cast to null errors.
The two changes are below:
var cipher = new RSAEngine()..init( true, new PublicKeyParameter<RSAPublicKey>(keyPair.publicKey)); cipher.init( false, new PrivateKeyParameter<RSAPrivateKey>r(keyPair.privateKey));
With these two changes, I got your code snippet to work and properly encode and decode "Hello World"
@mslavkovski @coylums
You are not providing the type in the generic classes in two of your lines where you create PublicKeyParameter and PrivateKeyParameter. I suspect the underlying code is casting to a T which is undefined, so you are getting cast to null errors.
The two changes are below:
var cipher = new RSAEngine()..init( true, new PublicKeyParameter<RSAPublicKey>(keyPair.publicKey)); cipher.init( false, new PrivateKeyParameter<RSAPrivateKey>r(keyPair.privateKey));
With these two changes, I got your code snippet to work and properly encode and decode "Hello World"
That was indeed the issue there. Now it works.
Thanks!
can you share decrypt function ?
Migrating from BigInteger to Dart 2's BigInt introduced an issue with the RSA Key Generator.
The PR introducing the issue is here: https://github.com/PointyCastle/pointycastle/pull/122
This could be solved by https://github.com/dart-lang/sdk/issues/32626, but I'm currently unable to test this.