001package com.bitbucket.thinbus.srp6.js; 002 003import java.math.BigInteger; 004import java.nio.charset.Charset; 005import java.nio.file.Files; 006import java.nio.file.Paths; 007import java.security.MessageDigest; 008import java.util.List; 009import java.util.regex.Matcher; 010import java.util.regex.Pattern; 011 012import com.nimbusds.srp6.SRP6Routines; 013 014/** 015 * A class to parse the output of 'openssl dhparam -text bits' where bits is the 016 * prime number bit length. Will output 'N', 'g', 'k' in bases 10, 10, 16 017 * respectively. Note that k is derived from 'N' and 'g' but Nimbus 1.4.x 018 * currently uses a the byte array constructor of BigInteger to computes 'k' 019 * which is not available in Javascript so the value genenerated by Java needs 020 * to be configure in the Javascript. 021 */ 022public class OpenSSLCryptoConfig { 023 public static void main(String[] args) throws Exception { 024 System.out.println(String.format("attempting to open a openssl dhparam text file at: %s", args[0])); 025 026 List<String> lines = Files.readAllLines(Paths.get(args[0]), Charset.forName("UTF8")); 027 028 StringBuilder hexparts = new StringBuilder(); 029 030 int bits = 0; 031 int generator = 0; 032 033 for (String line : lines) { 034 if (line.startsWith("Diffie-Hellman-Parameters:")) { 035 try { 036 bits = bits(line); 037 } catch (Exception e) { 038 throw new AssertionError("could not parse 'xxxx bit' number out of line beginning 'Diffie-Hellman-Parameters'"); 039 } 040 } else if (line.endsWith("prime:")) { 041 // skip this one 042 } else if (line.endsWith(":")) { 043 hexparts.append(line.trim()); 044 } else if (line.contains("generator")) { 045 try { 046 generator = generator(line); 047 } catch (Exception e) { 048 throw new AssertionError("could not parse 'generator: x' number out of line containing 'generator'"); 049 } 050 } 051 } 052 053 if (bits <= 0) { 054 throw new AssertionError("could not parse 'xxxx bit' number out of line beginning 'Diffie-Hellman-Parameters'"); 055 } 056 057 if (generator <= 0) { 058 throw new AssertionError("could not parse 'generator: x' number out of line containing 'generator'"); 059 } 060 061 String primeHex = hexparts.toString().replace(":", ""); 062 063 System.out.println("bits:" + bits); 064 065 BigInteger N = new BigInteger(primeHex, 16); 066 BigInteger g = new BigInteger(generator + ""); 067 068 System.out.println("hashing to create 'k' using " + args[1]); 069 070 MessageDigest digest = MessageDigest.getInstance(args[1]); 071 BigInteger k = SRP6Routines.computeK(digest, N, g); 072 073 System.out.println("computing"); 074 System.out.println("N base10: " + N.toString(10)); 075 System.out.println("g base10: " + g.toString(10)); 076 System.out.println("k base16: " + k.toString(16)); 077 } 078 079 static Pattern generatorPattern = Pattern.compile(".*generator: (\\d*) \\(.*"); 080 081 private static int generator(String line) { 082 Matcher matcher = generatorPattern.matcher(line); 083 matcher.matches(); 084 String number = matcher.group(1); 085 return Integer.valueOf(number); 086 } 087 088 static Pattern bitsPattern = Pattern.compile(".*\\((\\d*) bit\\).*"); 089 090 private static int bits(String line) { 091 Matcher matcher = bitsPattern.matcher(line); 092 matcher.matches(); 093 String number = matcher.group(1); 094 return Integer.valueOf(number); 095 } 096 097}