bcgit / pc-dart

Pointy Castle - Dart Derived Bouncy Castle APIs
MIT License
237 stars 122 forks source link

Support for AES/CFB8 #124

Closed XanderNuytinck closed 3 years ago

XanderNuytinck commented 3 years ago

Pointy castle does not support AES/CFB8 (only AES/CFB64)

I am aware that CFB8 is outdated, but some people including me still require it. Thanks

licy183 commented 3 years ago

Actually, this library supports AES-CFB8.

import 'dart:convert';
import 'dart:typed_data';

import 'package:pointycastle/api.dart';

class BinAscii {
  static const String _ALPHABET = '0123456789abcdef';
  static const Map<String, int> _MAP = {
    '0': 0,
    '1': 1,
    '2': 2,
    '3': 3,
    '4': 4,
    '5': 5,
    '6': 6,
    '7': 7,
    '8': 8,
    '9': 9,
    'a': 10,
    'A': 10,
    'b': 11,
    'B': 11,
    'c': 12,
    'C': 12,
    'd': 13,
    'D': 13,
    'e': 14,
    'E': 14,
    'f': 15,
    'F': 15
  };
  static Uint8List unhexlify(String hexStr) {
    if (hexStr.length % 2 != 0) {
      hexStr = '0' + hexStr;
    }
    final result = List<int>.filled(hexStr.length ~/ 2, 0);
    for (var i = 0; i < result.length; ++i) {
      var firstDigit = _MAP[hexStr[i * 2]];
      if (firstDigit == null) {
        throw FormatException('Non-hexadecimal digit found');
      }
      var secondDigit = _MAP[hexStr[i * 2 + 1]];
      if (secondDigit == null) {
        throw FormatException('Non-hexadecimal digit found');
      }
      result[i] = (firstDigit << 4) + secondDigit;
    }
    return Uint8List.fromList(result);
  }

  static String hexlify(Uint8List payload) {
    var sb = StringBuffer();
    payload.forEach((element) {
      if (element & 0xff != element) {
        throw RangeError.range(element, 0, 255);
      }
      sb..write(_ALPHABET[element >> 4])..write(_ALPHABET[element & 0xf]);
    });
    return sb.toString();
  }
}

void main(List<String> arguments) {
  final key = BinAscii.unhexlify('00112233445566778899aabbccddeeff');
  final iv = Uint8List.fromList(key);
  final params = ParametersWithIV(KeyParameter(key), iv);
  final enc = BlockCipher('AES/CFB-8')..init(true, params);
  final msg = Uint8List.fromList(utf8.encode('This is a test string.\n'));
  final encMsgBuf = <int>[];
  for (var i = 0; i < msg.length; i += enc.blockSize) {
    encMsgBuf.addAll(enc.process(msg.sublist(i, i + enc.blockSize)));
  }
  print(BinAscii.hexlify(Uint8List.fromList(encMsgBuf)));
}
// 36f589ffb90288ceada97905a27168decf07b7e8d8511d
// Exited

The result is the same as openssl's output.

# echo This is a test string.| openssl enc -aes-128-cfb8 -K 00112233445566778899aabbccddeeff -iv 00112233445566778899aabbccddeeff -in -  | hex
36f589ffb90288ceada97905a27168decf07b7e8d8511d
XanderNuytinck commented 3 years ago

Thank you I appreciate you helping.