read

The NEM team would like to thank Owon for submitting this blog.

A quick walk through the project and code

Some weeks ago, I started to create paper wallets which are compatible with the mobile wallet client. At that time, it was an open question to me how the QR code for mobile wallet is built. This was a reason to dig into the topic and create a new version of my generator.

My initial version of the generator was done in Java. With the help of jabo38 (many thanks!), who pointed me to the sources of the Android wallet, I was able to find all relevant parts to create a JSON string, used as the input for the QR, which contains all information required by the mobile wallet.

An example of a JSON string which is compatible as input for the QR supported by the mobile wallets looks like this:

{"v":2,"type":3,"data":{"name":"walletname","priv_key":"15091560b15f5612b9bd08b61478aeae258cd4ba4cbfcb25e0064d862f5912e9afc737b57ab07d5c53d56c90dfd5db2a4cccd97fa7d40a93d21510dd420a18fa","salt":"9011cd94fb5790186207ff725ed26884701cee8af421383015de83e3c231fb2b"}}

The JSON data should be self explanatory with some remarks:

-Salt is 32bytes secure random salt data -The private key encoding & encryption is a bit more tricky. At first, a new PBKDF2 key (rounds equal to 2000) is generated from the salt and a user-specific password. The user password needs to be at least 6 characters to be supported by the mobile wallet. Once this new encryption key is built, it is used to AES encrypt the original private key combined with an initialization vector. The result is the final priv_key we are seeking for as shown in the JSON string above.

The following function takes the wallet name, the password string, the original private key and the secure random salt as a hex string as an input and returns the whole JSON string which can be directly used to create the QR code:

public static String GenEncsk(final String walletname, final String password, final String sk_string, final String salt_string){
try{
byte[] skbyte = hexStringToByteArray(sk_string);
byte[] saltbyte = hexStringToByteArray(salt_string);
char[] pwcharArray = password.toCharArray();

    // Generate encryption key from pw and salt
    PBEKeySpec keySpec = new PBEKeySpec(pwcharArray, saltbyte, 2000, 256);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
    SecretKey key = new SecretKeySpec(keyBytes, "AES");
    //System.out.println(key.getFormat());
    //System.out.println(key.getEncoded().length);


    //encrypt sk with previous generated key form salt and pw
    // Setup IV.
    final Random r1 = new SecureRandom();
    final byte[] ivData = new byte[16];
    r1.nextBytes(ivData);


    // Setup block cipher.
    final BufferedBlockCipher cipher =  setupBlockCipher(key.getEncoded(), ivData, true);

    // Encode.
    final byte[] buf =  transform(cipher, skbyte);

    final byte[] result = new byte[ivData.length + buf.length];
    System.arraycopy(ivData, 0, result, 0, ivData.length);
    System.arraycopy(buf, 0, result, ivData.length, buf.length);
    //return new BinaryData(result);

    //Extract encrypted key as hex-string for output
    final StringBuilder skbuilder = new StringBuilder();
    for(byte b : result) {
            skbuilder.append(String.format("%02x", b));
       }
    String skencoded =  skbuilder.toString();

    //Create final string for qr code
        final String mw_string = "{\"v\":2,\"type\":3,\"data\":{\"name\":\"" + walletname + "\",\"priv_key\":\"" + skencoded + "\",\"salt\":\""+ salt_string + "\"}}";


    return mw_string;
     } catch(Exception e){
        return e.toString();
    }

}

At this point we are already able to create mobile wallet compatible JSON strings, I figured out that Kodtycoon published a new API wrapper for NEM in C#. It's very interesting, and I decided to port the main paper wallet generator to C#.

As the function to create the mobile wallet, JSON was already finished in Java and it can be a mess to port crypto related services I decided to keep it there, at least for now. I used the IKVM.NET project which includes ikvmc, a Java bytecode to .NET IL translator to create a .NET compatible library out of a Java .class file. This library is used in my C# generator and is added as a reference to the project.

The command to port the .class file looks like this and drops out a nice .dll file:
ikvmc.exe -recurse:<path to references> -target:library voucher.class

I believe the rest of the generator code is straightforward:
- It contains the design of the form(s) and user interface - It creates the required secure random keys - Uses Kodtycoon's C# wrapper to create NEN main-net keypairs - Processes some error checking - Creates the QR codes with ZXing.Net

The sources for the generator are available on Github: https://github.com/owon/voucher-paper_wallet

A precompiled version is available here. (please always verify me as the publisher with Apostille)

The forum entry can be found here: https://forum.nem.io/t/voucher-paper-wallet-generator/2998

If you have further questions and/or remarks regarding the voucher & paper wallet generator, please send me a forum PM.

Thanks! - Owon

Blog Logo

A Nember


Published


Image

NEM

Official Blog of NEM/XEM

Back to Overview