PointyCastle / pointycastle

Moved into the Bouncy Castle project: https://github.com/bcgit/pc-dart
MIT License
270 stars 76 forks source link

RegistryFactoryException: No algorithm registered of type SecureRandom with name #149

Closed StarOfLife closed 6 years ago

StarOfLife commented 6 years ago

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)

#6 main (file:///F:/dart/lib/main.dart:58:10) #7 _startIsolate. (dart:isolate/runtime/libisolate_patch.dart:286:19) #8 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:169:12)
StarOfLife commented 6 years ago

when I use the PKCS1Encoding, it throw a error

yshrsmz commented 6 years ago

https://github.com/PointyCastle/pointycastle/blob/00c64f2ba8e5faa180f6e2d04653df70bb37b0b9/lib/asymmetric/pkcs1.dart#L48

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.

StarOfLife commented 6 years ago

yes,now I‘m create a self pkcs1padding function instead of PKCS1Encoding

ikecoolon commented 5 years ago

@StarOfLife How to create a self pkcs1padding? Could you show me the class?

StarOfLife commented 5 years ago

@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);
}