Pre-Shared Key Generation

From CT3

Jump to: navigation, search

Long and good random strings of characters are desired to create good pre-shared secrets for authenticating IPsec sessions (or any other security mechanism that relies on shared secrets).


Microsoft Cryptographic Application Programming Interface

The Microsoft’s CryptGenRandom function is FIPS-186-2 compliant and should provide adequate strength in randomness. It is part of the Microsoft Cryptographic Application Programming Interface which is available in Microsoft operating systems. The function uses some more or less random sources available to the operating system that should be difficult to predict/guess in order to perform a timely brute-force attack on the random number generator. The sources of information include:

  • Process ID
  • Thread ID
  • Tick count since boot time
  • Current time
  • Performance counters
  • A hash of the user's environment (e.g. username, computer name, various paths)
  • CPU counters
  • Etc.

Perl Script for Generating Good Random Pre-Shared Keys

The following script can be used to generate good random pre-shared secrets for IPsec. It requires ActiveState Perl and makes use of the CryptGenRandom function. The script generates 43 characters that almost equal 256-bit strength (there is some loss due to exclusion of two characters).

use Win32;
use Win32::API;
use Win32::Clipboard;
use MIME::Base64;              # Use Base64 to convert binary key to ASCII
my $CLIP = Win32::Clipboard(); # Use the clipboard to simplify pre-shared key (PSK) management
my $ps;                        # Variable to hold the final result for multiple PSKs
my $p="";                      # Variable to hold the final result for a single PSK
my $num=1;                     # If there is no argument, provide one pre-shared key
if ($#ARGV>=0){$num=$ARGV[0];} # If there is an argument, it is the number of PSKs to provide
$CT=new Win32::API "advapi32","CryptAcquireContextA",'PNNNN','N'||die "$^E\n"; # Use MS crypto or die
    $GR=new Win32::API "advapi32", 
      "CryptGenRandom",'NNP','N'||die "$^E\n"; # Microsoft's FIPS-compliant random number generator
    my $rnd = "\0" x 32;                       # Format 32-byte (256-bit) variable (i.e. malloc)
    my $h = "\0" x 4;                          # Format 4-byte temporary variable (i.e. malloc)
    my $r=$CT->Call($h,0,0,1,0xF0000000);      # Acquire context
    $h=unpack('L',$h);                         # Unpack the four bytes
    $r=$GR->Call($h,32,$rnd);                  # Call random-number generator
    $p=encode_base64($rnd,"\0");               # Convert binary to ascii
    chop($p); chop($p);                        # Remove final '='
  }while($p=~/[\/\+]/);                        # Find a value without '/' or '+' (slight loss)
  $ps.=$p.chr(13).chr(10);                     # Concatenate PSKs
if ($ARGV[0]){
  Win32::MsgBox("$ARGV[0] pre-shared keys have been copied to the clipboard.",0);
  Win32::MsgBox("Pre-shared key '$p' has been copied to the clipboard.",0);


  • Download and install ActiveState Perl.
  • Create a text file called
  • Copy the above source code into the text file and save it.

Usage guidelines

Usage: [number]

  • number: This optional parameter determines how many pre-shared keys should be generated and copied to the clipboard. If omitted, only one pre-shared key is generated.


Bostjan Sustar, © 2008 NIL Data Communications

Personal tools


Main menu