crypt 3.0.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 91

crypt #

One-way string hashing for salted passwords using the Unix crypt format.

This package implements the SHA-256 crypt hash and SHA-512 crypt hash, as specified by "Unix crypt using SHA-256 and SHA-512" (version: 0.6 2016-08-31).

Crypt format strings #

It can produce crypt formatted string like:

$5$xYWYo0raYwLSchAd$na8cL1H.ESWtof6DNwraE6p8WI9DYObZ3irMe01Guk6

and

$5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2.opqey6IcA

Where the leading "$5$" indicates this is a SHA-256 crypt, and is followed a number of fields separated by the dollar sign: a optional the number of rounds, the salt and the hash value. A leading "$6$" indicates it is a SHA-512 crypt.

When SHA-256 or SHA-512 is being used, the default number of rounds is 5000 (as defined by the specification).

Note: different systems use the crypt formatted string differently. For example, as the value of the userPassword attribute in an LDAP posixAccount entry, "{crypt}" needs to be prepended to it.

Usage #

import 'package:crypt/crypt.dart';

void main() {
  // Creating crypt strings

  // Default rounds and random salt generated
  final c1 = Crypt.sha256('p@ssw0rd');

  // Random salt generated
  final c2 = Crypt.sha256('p@ssw0rd', rounds: 10000);

  // Default rounds
  final c3 = Crypt.sha256('p@ssw0rd', salt: 'abcdefghijklmnop');

  // No defaults used
  final c4 = Crypt.sha256('p@ssw0rd', rounds: 10000,
                          salt: 'abcdefghijklmnop');

  // SHA-512
  final d1 = Crypt.sha512('p@ssw0rd');

  print(c1);
  print(c2);
  print(c3);
  print(c4);
  print(d1);

  // Comparing a value to a crypt hash

  for (final hashString in [
    r'$5$zQUCjEzs9jnrRdCK$dbo1i9WjQjbUwOC4JCRAZHpfd31Dh676vI0L6w0dZw1',
    c1.toString(),
    c2.toString(),
    c3.toString(),
    c4.toString(),
    d1.toString(),
  ]) {
    // Parse the crypt string: this extracts the type, rounds and salt
    final h = Crypt(hashString);

    final correctValue = 'p@ssw0rd';
    final wrongValue = '123456';

    if (!h.match(correctValue)) {
      print('Error: unexpected non-match: $correctValue');
    }

    if (h.match(wrongValue)) {
      print('Error: unexpected match: $wrongValue');
    }
  }
}

The above example produced the following output:

$5$jYq8PvB6hI3cLREQ$FGBjCL5NO1qSwync3LOlCWTnIBJCjVsFtst9jNnnBx9
$5$rounds=10000$wJiiNy1TwwaWhGFN$t2JsIqOgfXh/3LLQF.YA9XDlJmtpLYmSe4i9TZl7cM.
$5$abcdefghijklmnop$gUWLu9sDI2Qvs112Xb8jmgD3ySIRE5ek63jk6ybSs7D
$5$rounds=10000$abcdefghijklmnop$51muKIziT9VAyDZ2ZueAYvAwgIYx0cLxUCIAlPoWaHD
$6$LJgzW1oI9UZ5w8HO$pTL3hmFg2zBkQPqRhcej6CmY2Az0WLDVlnMGTg//71D3hDEvKCB7XqwtinHEM1rlD/YAlEjhy2Lb3LJQsNvXx.

Features and bugs #

Salt generation does not use a cryptographically secure random number generator. If this is a concern, generate your own salt and pass it in as one of the parameters.

Version 3.0.0 depends on the Dart crypto package, version 2.1.4 or newer, which has support for SHA-512. If you need to use an older version of crypto, use version 2.0.0 of this package -- but that older version won't have support for SHA-512 crypt strings.

Please file feature requests and bugs at the GitHub issue tracker.

Changelog #

3.0.0 #

  • Added support for SHA-512 (which requires upgrading to crypto 2.1.0 or later).

2.0.0 #

  • Code clean up to satisfy pana 0.13.2 health checks.
  • Updated minimum dependency to Dart 2.3.

1.0.7 #

  • Added hashCode property.
  • Fixed dartanalyzer warnings.

1.0.6 #

  • Updated the upper bound of the SDK constraint to <3.0.0.

1.0.5 #

  • Code made sound to support Dart strong mode.

1.0.4 #

  • Updated dependency to allow usage of crypto verson 2.0.2.

1.0.3 #

  • Make compatible with Angular 2 version 3.1.

1.0.2 #

  • Fixed parsing bug.

1.0.1 #

  • Co-exist with other packages that depend on version 0.x.x of crypto.

1.0.0 #

  • Match method and equality operator added.
  • Changed to represent the crypt as an object with a toString method.

0.0.1 #

  • Initial release.

example/example.dart

// Copyright (c) 2015, 2016, 2017, 2020, Hoylen Sue. All rights reserved. Use of this source code
// is governed by a BSD-style license that can be found in the LICENSE file.

import 'package:crypt/crypt.dart';

void main() {
  // Creating crypt strings
  //
  // For example, when someone updates their password, generate a crypt hash
  // string from it and save the crypt hash string in a database. Never store
  // the plaintext password.

  // Default rounds and random salt generated
  final c1 = Crypt.sha256('p@ssw0rd');

  // Random salt generated
  final c2 = Crypt.sha256('p@ssw0rd', rounds: 10000);

  // Default rounds
  final c3 = Crypt.sha256('p@ssw0rd', salt: 'abcdefghijklmnop');

  // No defaults used
  final c4 = Crypt.sha256('p@ssw0rd', rounds: 10000, salt: 'abcdefghijklmnop');

  // SHA-512
  final d1 = Crypt.sha512('p@ssw0rd');

  print(c1);
  print(c2);
  print(c3);
  print(c4);
  print(d1);

  // Note: the crypt strings that have randomly generated salts will produce
  // different values every time the program runs. The crypt strings that uses
  // fixed salts, will always produce the same values.

  // Comparing a value to a crypt hash
  //
  // For example, the crypt hash string is stored in a database. When someone
  // tries to sign in, it is retrieved from the database and compared to the
  // password they have entered. If match returns true, they have provided the
  // original value that was used to create the crypt hash string.

  for (final hashString in [
    r'$5$zQUCjEzs9jnrRdCK$dbo1i9WjQjbUwOC4JCRAZHpfd31Dh676vI0L6w0dZw1',
    c1.toString(),
    c2.toString(),
    c3.toString(),
    c4.toString(),
    d1.toString(),
  ]) {
    // Parse the crypt string: this extracts the type, rounds and salt
    final h = Crypt(hashString);

    final correctValue = 'p@ssw0rd';
    final wrongValue = '123456';

    if (!h.match(correctValue)) {
      print('Error: unexpected non-match: $correctValue');
    }

    if (h.match(wrongValue)) {
      print('Error: unexpected match: $wrongValue');
    }
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  crypt: ^3.0.0

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:crypt/crypt.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
82
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
91
Learn more about scoring.

We analyzed this package on Jul 2, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.13

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.3.0 <3.0.0
crypto ^2.1.4 2.1.5
Transitive dependencies
charcode 1.1.3
collection 1.14.13
convert 2.1.1
typed_data 1.2.0
Dev dependencies
test >=0.12.10 <1.13.0