Log in

View Full Version : Question of BigInteger ...


gordon_freeman
November 3rd, 2003, 15:52
Hi,
I'm trying to make a keygenerator for an application that use the following code to valiate the license informations :


public static ProductDescriber check ( String username , String key ) throws
InvalidKeyException
{
// A key form is : xxxxx-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx

BigInteger modulus = new BigInteger ( "86f71688cdd2612ca117d1f54bdae029" , 16 ) ;
BigInteger exponent = new BigInteger ( "10001" , 16 ) ;

ProductDescriber e1 = new ProductDescriber () ;
e1.m_sUserName = username ;
int i = 0 ;
for ( int j = 0 ; j < key.length () ; j++ )
{
if ( key.charAt ( j ) == '-' )
i++ ;
}
// i = number of dashes in the key


if ( i != 5 && i != 4 )
throw new InvalidKeyException () ;
if ( i == 5 )
{
int k = key.indexOf ( '-' ) ;
try
{
e1.m_iCustomerId = Integer.parseInt ( key.substring ( 0 , k ) ) ;
key = key.substring ( k + 1 ) ;
}
catch ( NumberFormatException numberformatexception )
{
throw new InvalidKeyException () ;
}
}
else
{
e1.m_iCustomerId = -1 ;
}
BigInteger biginteger = Util.getBigInteger ( key ) ;

BigInteger biginteger1 = biginteger.modPow ( exponent , modulus ) ;

byte buffer[] = biginteger1.toByteArray () ;
if ( buffer.length != 12 )
if ( buffer.length == 13 )
{
if ( buffer[ 0 ] == 0 )
{
byte abyte1[] = new byte[ 12 ] ;
System.arraycopy ( buffer , 1 , abyte1 , 0 , 12 ) ;
buffer = abyte1 ;
}
else
{
throw new InvalidKeyException () ;
}
}
else
if ( buffer.length < 12 )
{
byte abyte2[] = new byte[ 12 ] ;
System.arraycopy ( buffer , 0 , abyte2 , 12 - buffer.length
, buffer.length ) ;
buffer = abyte2 ;
}
else
{
throw new InvalidKeyException () ;
}
if ( username != null )
{
short crc32 = Util.getChecksum ( username , e1.m_iCustomerId , buffer ) ;
if ( buffer[ 10 ] != ( byte ) ( crc32 & 0xff ) )
throw new InvalidKeyException () ;
if ( buffer[ 11 ] != ( byte ) ( crc32 >> 8 & 0xff ) )
throw new InvalidKeyException () ;
}
e1.m_iLicenseType = buffer[ 0 ] >> 4 ;
e1.m_iProductId = buffer[ 0 ] & 0xf ;
e1.m_iLicenseNumber = ( buffer[ 8 ] & 0xff ) + ( ( buffer[ 9 ] & 0xff ) << 8 ) ;
e1.m_iMinorVersion = buffer[ 1 ] >> 4 ;
e1.m_iMajorVersion = buffer[ 1 ] & 0xf ;
long l = ( ( ( long ) buffer[ 2 ] & 255L ) )
+ ( ( ( long ) buffer[ 3 ] & 255L ) << 8 )
+ ( ( ( long ) buffer[ 4 ] & 255L ) << 16 )
+ ( ( ( long ) buffer[ 5 ] & 255L ) << 24 ) << 16 ;

e1.m_dGenerationDate = new Date ( l ) ;
int i1 = ( buffer[ 6 ] & 0xff ) + ( ( buffer[ 7 ] & 0xff ) << 8 ) ;

if ( i1 != 0 )
e1.m_dExpirationDate = new Date ( l
+ ( long ) i1 * 24L * 60L * 60L * 1000L ) ;
return e1 ;
}

// Methods required from Class Util

public static short getChecksum ( String username , int customerId
, byte bigIntegerBuffer[] )
{
CRC32 crc32 = new CRC32 () ;
if ( username != null )
{
for ( int j = 0 ; j < username.length () ; j++ )
crc32.update ( username.charAt ( j ) ) ;
}
crc32.update ( customerId ) ;
crc32.update ( customerId >> 8 ) ;
crc32.update ( customerId >> 16 ) ;
crc32.update ( customerId >> 24 ) ;
for ( int k = 0 ; k < bigIntegerBuffer.length - 2 ; k++ )
crc32.update ( bigIntegerBuffer[ k ] ) ;

return ( short ) ( int ) crc32.getValue () ;
}

public static BigInteger getBigInteger(String key)
throws InvalidKeyException{
BigInteger biginteger = BigInteger.ZERO;
int i = key.length();
BigInteger biginteger1 = BigInteger.valueOf(0x39aa400L);
int j;
for(; i >= 0; i = j - 1)
{
j = key.lastIndexOf('-', i - 1) + 1;
String s1 = key.substring(j, i);
int k = b(s1);
biginteger = biginteger.multiply(biginteger1);
biginteger = biginteger.add(BigInteger.valueOf(k));
}

return biginteger;
}

public static int b(String s)
throws InvalidKeyException{
if(s.length() != 5)
throw new InvalidKeyException();
int i = 0;
for(int j = s.length() - 1; j >= 0; j--)
{
char c = s.charAt(j);
int k;
if('0' <= c && c <= '9')
k = c - 48;
else
if('A' <= c && c <= 'Z')
k = (c - 65) + 10;
else
throw new InvalidKeyException();
i *= 36;
i += k;
}
return i;
}

// Class ProductDescriber
public class ProductDescriber {
.....
public String m_sUserName ;
public int m_iCustomerId ;
public int m_iProductId ;
public int m_iLicenseType ;
public int m_iLicenseNumber ;
public int m_iMajorVersion ;
public int m_iMinorVersion ;
public Date m_dGenerationDate ;
public Date m_dExpirationDate ;
}


My question is how to make a keygenerator for this ?
I don't have a good knowledge about BigInteger and the modulus operations.
I am especially interested in the mathematical background of reversing this.

Thank you.

Solomon
November 3rd, 2003, 20:53
It's RSA algo and CRC32.
N = 86f71688cdd2612ca117d1f54bdae029,
E = 10001

It's not difficult to factor N. The class ProductDescriber gives us the details of the license bits. If you are familiar with Java and some RSA concept, you can keygen it.

gordon_freeman
November 5th, 2003, 18:15
Hi,
Thank you Solomon for your help.

Using the extended Euclidean algorithm : gcd( e, phi), i finally found that :
d = 430d187de8bb3f18fb0a986e6b7163bd

Thank you.