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.
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.