diff --git a/lib/src/cryptographic.dart b/lib/src/cryptographic.dart index 6d70851..88c1b01 100644 --- a/lib/src/cryptographic.dart +++ b/lib/src/cryptographic.dart @@ -166,4 +166,22 @@ class Cryptographic { ).replaceAll('=', '').substring(0, length); return '$prefix$key'; } + + /// Returns certificate fingerprint. + /// + /// [asSha256] determines whether returned string looks like sha256 or sha1 + /// (default is true). + /// + /// Example: + /// ```dart + /// Cryptographic().certificateFingerprint(); // "74:67:A0:9C:B6:49:9B:B1:51:74:C2:9F:6C:42:81:52:5C:7A:31:F5:72:75:09:A0:41:08:1F:53:31:E7:D7:41" + /// Cryptographic().certificateFingerprint(asSha256: false); // "93:5E:AE:6E:89:6B:CF:C4:76:DD:6D:23:50:10:80:6C:22:9D:55:90" + /// ``` + String certificateFingerprint({bool asSha256 = true}) { + final hexString = asSha256 ? tokenHex() : tokenHex(entropy: 20); + return [ + for (var i = 0; i < hexString.length; i += 2) + hexString.substring(i, i + 2), + ].join(':').toUpperCase(); + } } diff --git a/test/src/cryptographic_test.dart b/test/src/cryptographic_test.dart index bf0ee2a..fd42e9f 100644 --- a/test/src/cryptographic_test.dart +++ b/test/src/cryptographic_test.dart @@ -192,5 +192,35 @@ void main() { ); } }); + + test('returns certificate fingerprint with default params', () { + final result = crypto.certificateFingerprint(); + expect(result.length, equals(95)); // 32 bytes * 2 hex chars + 31 colons + expect(":".allMatches(result).length, 31); + expect(result.contains(RegExp('[A-Z]')), isTrue); + expect( + seededCrypto.certificateFingerprint(), + equals(seededCrypto.certificateFingerprint()), + ); + }); + + test('returns ertificate fingerprint with provided params', () { + const params = [ + // [asSha256, expectedLength, expectedColons] + (true, 95, 31), // 32 bytes = 64 hex chars + 31 colons = 95 total + (false, 59, 19), // 20 bytes = 40 hex chars + 19 colons = 59 total + ]; + + for (final (asSha256, expectedLength, expectedColons) in params) { + final result = crypto.certificateFingerprint(asSha256: asSha256); + expect(result.length, equals(expectedLength)); + expect(":".allMatches(result).length, expectedColons); + expect(result.contains(RegExp('[A-Z]')), isTrue); + expect( + seededCrypto.certificateFingerprint(asSha256: asSha256), + equals(seededCrypto.certificateFingerprint(asSha256: asSha256)), + ); + } + }); }); }