Closed StarOfLife closed 6 years ago
when I use the PKCS1Encoding, it throw a error
looks like PKCS1Encoding
is trying to instantiate SecureRandom
with empty algorithm name which does not exist.
I guess you can use ParametersWithRandom
and pass SecureRandom
instance explicitly.
yes,now I‘m create a self pkcs1padding function instead of PKCS1Encoding
@StarOfLife How to create a self pkcs1padding? Could you show me the class?
@ikecoolon
import 'dart:typed_data';
import 'dart:math';
import 'dart:convert';
import 'package:asn1lib/asn1lib.dart';
import 'package:pointycastle/export.dart';
import 'package:pointycastle/asymmetric/api.dart';
import 'package:pointycastle/asymmetric/rsa.dart';
BigInt _parseKey(String pem) {
//从公钥里面解析出e来。默认n就是65537了
List<int> publicKey = decodePEM(pem);
var asn1Parser = new ASN1Parser(publicKey);
var topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
var publicKeyBitString = topLevelSeq.elements[1];
asn1Parser = new ASN1Parser(publicKeyBitString.contentBytes());
var pkSeq = asn1Parser.nextObject() as ASN1Sequence;
return (pkSeq.elements[0] as ASN1Integer).valueAsBigInteger;
}
List<int> decodePEM(pem) {
var startsWith = [
"-----BEGIN PUBLIC KEY-----",
"-----BEGIN PRIVATE KEY-----"
];
var endsWith = ["-----END PUBLIC KEY-----", "-----END PRIVATE KEY-----"];
//HACK
for (var s in startsWith) {
if (pem.startsWith(s)) pem = pem.substring(s.length);
}
//Dart base64 decoder does not support line breaks
pem = pem.replaceAll('\n', '');
pem = pem.replaceAll('\r', '');
for (var s in endsWith) {
if (pem.endsWith(s)) pem = pem.substring(0, pem.length - s.length);
}
return base64.decode(pem);
}
List<int> _pkcs1pad(
String input, int outOff, RSAEngine _engine, bool publikKey) {
// 补码用,没有考虑太多的情况,仅仅是原文小于128位的情况
Uint8List inp = Uint8List.fromList(input.codeUnits);
if (inp.length > _engine.inputBlockSize) {
throw new ArgumentError("Input data too large");
}
var block = new Uint8List(_engine.inputBlockSize);
var padLength = (block.length - inp.length - 1);
if (!publikKey) {
block[0] = 0x01; // type code 1
block.fillRange(1, padLength, 0xFF);
} else {
block[0] = 0x02; // type code 2
block.setRange(1, padLength, _random(padLength - 1));
// a zero byte marks the end of the padding, so all
// the pad bytes must be non-zero.
for (var i = 1; i < padLength; i++) {
while (block[i] == 0) {
block[i] = _nextUint8();
}
}
}
block[padLength] = 0x00; // mark the end of the padding
block.setRange(padLength + 1, block.length, inp);
var outSize = _engine.outputBlockSize;
var out = new Uint8List(outSize);
var len = _engine.processBlock(block, 0, block.length, out, outOff);
return out.sublist(0, len);
}
_random(int len) {
int i = 0;
List<int> list = List(len);
while (i < len) {
list[i] = Random().nextInt(255);
i++;
}
return list;
}
_nextUint8() {
var i = Random().nextInt(255);
return i == 0 ? 25 : i;
}
/*
*@params{String str,String publicKey}
传入要加密的字符串,加密所用的base64格式的公钥
*/
String rsaEncrypt(String str, String publicKey) {
final pubk = RSAPublicKey(_parseKey(publicKey), BigInt.from(65537));
var pubpar = () => new PublicKeyParameter<RSAPublicKey>(pubk);
var engine = new RSAEngine();
engine.reset();
engine.init(true, pubpar());
List<int> list = _pkcs1pad(str, 0, engine, true);
return base64.encode(list);
}
Unhandled exception: RegistryFactoryException: No algorithm registered of type SecureRandom with name:
0 _RegistryImpl._createConstructor (package:pointycastle/src/registry/registry.dart:137:5)
1 _RegistryImpl.getConstructor (package:pointycastle/src/registry/registry.dart:108:21)
2 _RegistryImpl.create (package:pointycastle/src/registry/registry.dart:98:42)
3 new SecureRandom (file:///C:/Users/A1/AppData/Roaming/Pub/Cache/git/pointycastle-3cb81af114bdcdfe08fc09eb18a059b30757c8ad/lib/src/api/secure_random.dart:19:16)
4 PKCS1Encoding.init (package:pointycastle/asymmetric/pkcs1.dart:48:21)
5 main._getKey (file:///F:/dart/lib/main.dart:40:11)