Example usage for org.bouncycastle.crypto.generators SCrypt generate

List of usage examples for org.bouncycastle.crypto.generators SCrypt generate

Introduction

In this page you can find the example usage for org.bouncycastle.crypto.generators SCrypt generate.

Prototype

public static byte[] generate(byte[] P, byte[] S, int N, int r, int p, int dkLen) 

Source Link

Document

Generate a key using the scrypt key derivation function.

Usage

From source file:ch.lamacrypt.internal.crypto.GCMCipher.java

License:Open Source License

/**
 * Encrypts a given file with AES-256 in GCM mode of operation
 * <p>/*w  ww.  j a  v  a2  s  .  c  om*/
 * Reads data from the InputStream and writes the encrypted data to the
 * OutputStream
 *
 * @param inputFile
 * @return
 * @throws java.io.IOException
 * @throws java.security.InvalidKeyException
 * @throws java.security.InvalidAlgorithmParameterException
 * @throws javax.crypto.BadPaddingException
 * @throws javax.crypto.IllegalBlockSizeException
 */
protected int encrypt_V00(File inputFile) throws IOException, InvalidKeyException,
        InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException {
    DefaultFrame.setFileQueueItemStatus("Generating header");

    // getting the encryption password
    char[] pass = DefaultCipher.getEncryptionPassword();
    // generating Sx, Nx, R, Kx
    final byte[] Sk1 = GPCrypto.randomGen(Sk_BYTES), Sk2 = GPCrypto.randomGen(Sk_BYTES),
            Sn1 = GPCrypto.randomGen(Sn_BYTES), Sn2 = GPCrypto.randomGen(Sn_BYTES),
            byteFileCnt = GPCrypto.intToByteArray(intFileCnt),
            epoch = DatatypeConverter.parseHexBinary(Long.toHexString(NTP.getTime() / 1000)),
            N1 = new byte[] { Sn1[0], Sn1[1], Sn1[2], Sn1[3], Sn1[4], Sn1[5], byteFileCnt[0], byteFileCnt[1],
                    epoch[0], epoch[1], epoch[2], epoch[3] },
            N2 = new byte[] { Sn2[0], Sn2[1], Sn2[2], Sn2[3], Sn1[4], Sn1[5], byteFileCnt[0],
                    (byte) (byteFileCnt[1] + 0x01), epoch[0], epoch[1], epoch[2], (byte) (epoch[3] + 0x01) },
            R = GPCrypto.randomGen(R_BYTES);
    final SecretKey K1 = new SecretKeySpec(SCrypt.generate(GPCrypto.charToByte(pass), Sk1,
            (int) Math.pow(2, K1_KDF_N), KDF_r, KDF_p, CIPHER_KEY_BITS / 8), 0, CIPHER_KEY_BITS / 8, "AES"),
            K2 = new SecretKeySpec(
                    SCrypt.generate(R, Sk2, (int) Math.pow(2, K2_KDF_N), KDF_r, KDF_p, CIPHER_KEY_BITS / 8), 0,
                    CIPHER_KEY_BITS / 8, "AES");

    // writing header
    this.cipher.init(Cipher.ENCRYPT_MODE, K1, new GCMParameterSpec(GCM_TAG_BITS, N1, 0, GCM_NONCE_BYTES));
    dos.write((byte) 0x00);
    dos.write(Sk1);
    dos.write(N1);
    dos.write(DatatypeConverter.parseHexBinary(Integer.toHexString(K1_KDF_N)));
    dos.write(cipher.doFinal(R));
    dos.write(Sk2);
    dos.write(N2);
    dos.write(DatatypeConverter.parseHexBinary(Integer.toHexString(K2_KDF_N)));

    // encrypting file
    DefaultFrame.setFileQueueItemStatus("Uploading (0%)");
    this.cipher.init(Cipher.ENCRYPT_MODE, K2, new GCMParameterSpec(GCM_TAG_BITS, N2, 0, GCM_NONCE_BYTES));
    long fileSize = inputFile.length(), percentage = fileSize / 100L, bytesRead = 0L, iterCnt;

    // defining input stream and
    InputStream input = new FileInputStream(inputFile);

    if (fileSize < BUFFER_SIZE) {
        r = input.read(buf, 0, (int) fileSize);
        dos.write(this.cipher.doFinal(buf, 0, r));
    } else if (fileSize % BUFFER_SIZE == 0) {
        iterCnt = (fileSize / BUFFER_SIZE) - 1;

        for (long i = 0; i < iterCnt; i++) {
            input.read(buf);
            dos.write(this.cipher.update(buf));

            bytesRead += BUFFER_SIZE;
            if (bytesRead % percentage > 1) {
                updateStatus("Uploading (" + bytesRead / percentage + "%)");
            }
        }

        input.read(buf);
        dos.write(this.cipher.doFinal(buf));
    } else {
        iterCnt = fileSize / BUFFER_SIZE;

        for (long i = 0; i < iterCnt; i++) {
            input.read(buf);
            dos.write(this.cipher.update(buf));

            bytesRead += BUFFER_SIZE;
            if (bytesRead % percentage > 1) {
                updateStatus("Uploading (" + bytesRead / percentage + "%)");
            }
        }

        r = input.read(buf, 0, (int) (fileSize % BUFFER_SIZE));
        dos.write(this.cipher.doFinal(buf, 0, r));
    }

    updateStatus("Finalizing");

    // cleaning up
    GPCrypto.eraseByteArrays(Sk1, Sk2, epoch, N1, N2, R);
    GPCrypto.eraseKeys(K1, K2);
    GPCrypto.sanitize(pass);
    input.close();
    updateFileCnt();

    return dis.readInt();
}

From source file:ch.lamacrypt.internal.crypto.GCMCipher.java

License:Open Source License

/**
 * Decrypts a given file with AES-256 in GCM mode of operation
 *
 * @param outputFile/*from w  w  w  . ja v a  2  s .co  m*/
 * @return
 * @throws java.io.IOException
 * @throws java.security.InvalidKeyException
 * @throws java.security.InvalidAlgorithmParameterException
 * @throws javax.crypto.BadPaddingException
 * @throws javax.crypto.IllegalBlockSizeException
 */
protected int decrypt_V00(File outputFile) throws IOException, InvalidKeyException,
        InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException {
    updateStatus("Reading header");

    // getting file size and calculating iterCnt
    long fileSize = dis.readLong(), dlSize = fileSize + GCM_TAG_BITS / 8, iterCnt = dlSize / BUFFER_SIZE,
            percentage = dlSize / 100L, bytesRead = 0L;

    // defining output stream
    OutputStream output = new FileOutputStream(outputFile);

    // getting the encryption password
    char[] pass = DefaultCipher.getEncryptionPassword();

    // reading header
    byte[] header = new byte[234];
    dis.read(header, 0, 234);

    // reading Sx, Nx, scrypt factors and generating K1
    final byte[] S1 = Arrays.copyOfRange(header, 0, VS1), N1 = Arrays.copyOfRange(header, VS1, S1N1),
            K1_N = Arrays.copyOfRange(header, S1N1, N1K1N), S2 = Arrays.copyOfRange(header, K1NR, RS2),
            N2 = Arrays.copyOfRange(header, RS2, S2N2), K2_N = Arrays.copyOfRange(header, S2N2, N2K2N);
    final int K1_N_bak = (int) Math.pow(2, Integer.valueOf(Hex.toHexString(K1_N), 16)),
            K2_N_bak = (int) Math.pow(2, Integer.valueOf(Hex.toHexString(K2_N), 16));
    final SecretKey K1 = new SecretKeySpec(
            SCrypt.generate(GPCrypto.charToByte(pass), S1, K1_N_bak, KDF_r, KDF_p, CIPHER_KEY_BITS / 8), 0,
            CIPHER_KEY_BITS / 8, "AES");

    // reading E(K1, N1, R) 
    this.cipher.init(Cipher.DECRYPT_MODE, K1, new GCMParameterSpec(GCM_TAG_BITS, N1, 0, GCM_NONCE_BYTES));
    boolean failFree = true, AEADBadTag = false;
    byte[] R = new byte[64];

    try {
        R = cipher.doFinal(Arrays.copyOfRange(header, N1K1N, K1NR));
    } catch (IllegalBlockSizeException | BadPaddingException e) {
        failFree = false;
        updateStatus("Error");
        if (e instanceof javax.crypto.AEADBadTagException) {
            AEADBadTag = true;
        }
    }

    dos.writeBoolean(failFree);
    // decrypting file if no exception has been caught
    if (failFree) {
        // generating K2
        final SecretKey K2 = new SecretKeySpec(
                SCrypt.generate(R, S2, K2_N_bak, KDF_r, KDF_p, CIPHER_KEY_BITS / 8), 0, CIPHER_KEY_BITS / 8,
                "AES");

        updateStatus("Downloading (0%)");
        this.cipher.init(Cipher.DECRYPT_MODE, K2, new GCMParameterSpec(GCM_TAG_BITS, N2, 0, GCM_NONCE_BYTES));

        if (dlSize > BUFFER_SIZE) {
            if (dlSize % BUFFER_SIZE == 0) {
                iterCnt--;
            }

            // reading full blocks
            for (long i = 0; i < iterCnt; i++) {
                dis.readFully(buf);
                output.write(this.cipher.update(buf));

                bytesRead += BUFFER_SIZE;
                if (bytesRead % percentage > 1) {
                    updateStatus("Downloading (" + bytesRead / percentage + "%)");
                }
            }

            // reading last chunk
            if (dlSize % BUFFER_SIZE != 0) {
                r = dis.read(buf, 0, (int) dlSize % BUFFER_SIZE);
                output.write(this.cipher.doFinal(buf, 0, r));
            } else {
                dis.readFully(buf);
                output.write(this.cipher.doFinal(buf));
            }
        } else {
            r = dis.read(buf, 0, (int) dlSize);
            output.write(this.cipher.doFinal(buf, 0, r));
        }

        // erasing cryptographic parameters and closing streams
        updateStatus("Finalizing");
        GPCrypto.eraseByteArrays(header, S1, S2, N1, N2, R);
        GPCrypto.eraseKeys(K1, K2);
        GPCrypto.sanitize(pass);
        output.close();

        return dis.readInt();
    } else {
        // erasing cryptographic parameters and closing streams
        GPCrypto.eraseByteArrays(header, S1, S2, N1, N2, R);
        GPCrypto.eraseKeys(K1);
        GPCrypto.sanitize(pass);
        output.close();

        if (AEADBadTag) {
            return AEAD_EXCEPTION;
        } else {
            return 5;
        }
    }
}

From source file:ch.lamacrypt.internal.crypto.GCMCipher.java

License:Open Source License

protected static String getKey_V00(byte[] header)
        throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
        InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
    // getting the encryption password
    char[] pass = DefaultCipher.getEncryptionPassword();

    // reading Sx, Nx, scrypt factors and generating K1
    final byte[] S1 = Arrays.copyOfRange(header, 0, VS1), N1 = Arrays.copyOfRange(header, VS1, S1N1),
            K1_N = Arrays.copyOfRange(header, S1N1, N1K1N), S2 = Arrays.copyOfRange(header, K1NR, RS2),
            N2 = Arrays.copyOfRange(header, RS2, S2N2), K2_N = Arrays.copyOfRange(header, S2N2, N2K2N);
    final int K1_N_bak = (int) Math.pow(2, Integer.valueOf(Hex.toHexString(K1_N), 16)),
            K2_N_bak = (int) Math.pow(2, Integer.valueOf(Hex.toHexString(K2_N), 16));
    final SecretKey K1 = new SecretKeySpec(
            SCrypt.generate(GPCrypto.charToByte(pass), S1, K1_N_bak, KDF_r, KDF_p, CIPHER_KEY_BITS / 8), 0,
            CIPHER_KEY_BITS / 8, "AES");

    // reading E(K1, N1, R)
    Cipher cipher = Cipher.getInstance(CIPHER);
    cipher.init(Cipher.DECRYPT_MODE, K1, new GCMParameterSpec(GCM_TAG_BITS, N1, 0, GCM_NONCE_BYTES));

    byte[] R = new byte[64];
    boolean failFree = true;

    try {//  w  ww  .  j  av  a  2 s . c o m
        R = cipher.doFinal(Arrays.copyOfRange(header, N1K1N, K1NR));
    } catch (IllegalBlockSizeException | BadPaddingException ex) {
        failFree = false;
    }

    if (failFree) {
        // generating K2
        final SecretKey K2 = new SecretKeySpec(
                SCrypt.generate(R, S2, K2_N_bak, KDF_r, KDF_p, CIPHER_KEY_BITS / 8), 0, CIPHER_KEY_BITS / 8,
                "AES");

        GPCrypto.eraseByteArrays(header, S1, S2, N1, N2, R);
        GPCrypto.eraseKeys(K1);
        GPCrypto.sanitize(pass);

        return Hex.toHexString(K2.getEncoded());
    } else {
        GPCrypto.eraseByteArrays(header, S1, S2, N1, N2, R);
        GPCrypto.eraseKeys(K1);
        GPCrypto.sanitize(pass);

        return "error";
    }
}

From source file:ch.lamacrypt.internal.crypto.GPCrypto.java

License:Open Source License

/**
 * Derives a given string (usually a password) with scrypt, using the
 * following default values:/*from  ww  w  .j  av  a2 s. co  m*/
 * <ul>
 * <li>N=2^19</li>
 * <li>p=8</li>
 * <li>r=4</li>
 * </ul>
 *
 * @param password secret value to derive the key from
 * @param salt salt to use for this invocation
 * @param dkLen output size, in bytes
 * @return key derived from supplied password
 * @throws java.io.UnsupportedEncodingException
 */
public static byte[] scrypt(char[] password, byte[] salt, int dkLen) throws UnsupportedEncodingException {
    byte[] passBytes = charToByte(password),
            digest = SCrypt.generate(passBytes, salt, KDF_N, KDF_r, KDF_p, dkLen);
    sanitize(passBytes, SANITIZATION_COUNT);
    return digest;
}

From source file:cologne.eck.peafactory.crypto.kdf.ScryptKDF.java

License:Open Source License

@Override
public byte[] deriveKey(byte[] pswMaterial) {
    /*/*from  www .  ja va 2s .  c o m*/
    System.out.println("=== ScryptKDF deriveKey:");
    System.out.println("memoryFactor: " + memoryFactor 
          + ", cpuFactor: " + cPUFactor
          + ", parallelFactor: " + parallelFactor);
    Help.printBytes("Salt", KeyDerivation.getSalt());
    Help.printBytes("pswMaterial", pswMaterial);
    */

    if (KeyDerivation.getSalt().length < 16) {
        System.err.println("Warning: Scrypt: short salt.");
    }
    if (KeyDerivation.getSalt().length < 8) {
        System.err.println("Srypt: salt too short");
        throw new IllegalArgumentException("Scrypt - invalid salt size");
    }

    //long start =  System.currentTimeMillis(); // Startpunkt   
    byte[] keyMaterial = null;
    try {
        keyMaterial = SCrypt.generate(pswMaterial, KeyDerivation.getSalt(), cPUFactor, memoryFactor,
                parallelFactor, 64);
    } catch (Exception e) {
        System.err.println("ScryptKDF Exception.");
        e.printStackTrace();
    }
    //System.out.println("Scrypt: " + cPUFactor + " iterations, " + memoryFactor + " memory factor" );
    printInfos(true);

    keyMaterial = adjustKeyMaterial(keyMaterial);
    //Help.printBytes("keyMaterial", keyMaterial);
    return keyMaterial;
}

From source file:com.bitsofproof.supernode.api.ExtendedKey.java

License:Apache License

public static ExtendedKey createFromPassphrase(String passphrase, byte[] encryptedSeed)
        throws ValidationException {
    try {//w  w w  . ja  v a2s .c  o  m
        byte[] key = SCrypt.generate(passphrase.getBytes("UTF-8"), BITCOIN_SEED, 16384, 8, 8, 32);
        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding", "BC");
        SecretKeySpec keyspec = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keyspec);
        return create(cipher.doFinal(encryptedSeed));
    } catch (UnsupportedEncodingException e) {
        throw new ValidationException(e);
    } catch (IllegalBlockSizeException e) {
        throw new ValidationException(e);
    } catch (BadPaddingException e) {
        throw new ValidationException(e);
    } catch (InvalidKeyException e) {
        throw new ValidationException(e);
    } catch (NoSuchAlgorithmException e) {
        throw new ValidationException(e);
    } catch (NoSuchProviderException e) {
        throw new ValidationException(e);
    } catch (NoSuchPaddingException e) {
        throw new ValidationException(e);
    }
}

From source file:com.bitsofproof.supernode.api.KeyFormatter.java

License:Apache License

public String createBIP38Request(int lot, int sequence) throws ValidationException {
    byte[] result = new byte[49];

    SecureRandom random = new SecureRandom();
    byte[] ownersalt = null;
    byte[] ownentropy = new byte[8];
    if (lot != 0) {
        ownersalt = new byte[4];
        random.nextBytes(ownersalt);//from   www  .  ja  v a 2 s  .  c  o  m
        byte[] ls = BigInteger.valueOf(lot << 12 + sequence).toByteArray();
        System.arraycopy(ownersalt, 0, ownentropy, 0, 4);
        System.arraycopy(ls, Math.max(0, ls.length - 4), ownentropy, 4 + Math.max(0, 4 - ls.length),
                Math.min(4, ls.length));
    } else {
        ownersalt = new byte[8];
        random.nextBytes(ownersalt);
        ownentropy = ownersalt;
    }
    try {
        byte[] prefactor = SCrypt.generate(passphrase.getBytes("UTF-8"), ownersalt, 16384, 8, 8, 32);
        byte[] passfactor = prefactor;
        if (lot != 0) {
            byte[] tmp = new byte[32 + 8];
            System.arraycopy(prefactor, 0, tmp, 0, 32);
            System.arraycopy(ownentropy, 0, tmp, 32, 8);
            passfactor = Hash.hash(tmp);
        }
        ECKeyPair kp = new ECKeyPair(passfactor, true);
        byte[] passpoint = kp.getPublic();
        result[0] = (byte) 0x2C;
        result[1] = (byte) 0xE9;
        result[2] = (byte) 0xB3;
        result[3] = (byte) 0xE1;
        result[4] = (byte) 0xFF;
        result[5] = (byte) 0x39;
        result[6] = (byte) 0xE2;
        if (lot != 0) {
            result[7] = (byte) 0x53;
        } else {
            result[7] = (byte) 0x51;
        }
        System.arraycopy(ownentropy, 0, result, 8, 8);
        System.arraycopy(passpoint, 0, result, 16, 33);

    } catch (UnsupportedEncodingException e) {
    }
    return ByteUtils.toBase58WithChecksum(result);
}

From source file:com.bitsofproof.supernode.api.KeyFormatter.java

License:Apache License

private ECKeyPair parseBIP38NoEC(byte[] store, boolean compressed) throws ValidationException {
    byte[] addressHash = new byte[4];
    System.arraycopy(store, 3, addressHash, 0, 4);
    try {//from   ww w  .  j a  v a2 s . c  o  m
        byte[] derived = SCrypt.generate(passphrase.getBytes("UTF-8"), addressHash, 16384, 8, 8, 64);
        byte[] key = new byte[32];
        System.arraycopy(derived, 32, key, 0, 32);
        SecretKeySpec keyspec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding", "BC");
        cipher.init(Cipher.DECRYPT_MODE, keyspec);
        byte[] decrypted = cipher.doFinal(store, 7, 32);
        for (int i = 0; i < 32; ++i) {
            decrypted[i] ^= derived[i];
        }
        ECKeyPair kp = new ECKeyPair(decrypted, compressed);

        byte[] acs = Hash
                .hash(AddressConverter.toSatoshiStyle(kp.getAddress(), addressFlag).getBytes("US-ASCII"));
        byte[] check = new byte[4];
        System.arraycopy(acs, 0, check, 0, 4);
        if (!Arrays.equals(check, addressHash)) {
            throw new ValidationException("failed to decrpyt");
        }
        return kp;
    } catch (UnsupportedEncodingException e) {
        throw new ValidationException(e);
    } catch (NoSuchAlgorithmException e) {
        throw new ValidationException(e);
    } catch (NoSuchPaddingException e) {
        throw new ValidationException(e);
    } catch (InvalidKeyException e) {
        throw new ValidationException(e);
    } catch (IllegalBlockSizeException e) {
        throw new ValidationException(e);
    } catch (BadPaddingException e) {
        throw new ValidationException(e);
    } catch (NoSuchProviderException e) {
        throw new ValidationException(e);
    }
}

From source file:com.bitsofproof.supernode.api.KeyFormatter.java

License:Apache License

private ECKeyPair parseBIP38EC(byte[] store, boolean compressed, boolean hasLot) throws ValidationException {
    byte[] addressHash = new byte[4];
    System.arraycopy(store, 3, addressHash, 0, 4);

    byte[] ownentropy = new byte[8];
    System.arraycopy(store, 7, ownentropy, 0, 8);

    byte[] ownersalt = ownentropy;
    if (hasLot) {
        ownersalt = new byte[4];
        System.arraycopy(ownentropy, 0, ownersalt, 0, 4);
    }//from w w  w.  j a  v  a  2 s.com
    try {
        byte[] passfactor = SCrypt.generate(passphrase.getBytes("UTF-8"), ownersalt, 16384, 8, 8, 32);
        if (hasLot) {
            byte[] tmp = new byte[40];
            System.arraycopy(passfactor, 0, tmp, 0, 32);
            System.arraycopy(ownentropy, 0, tmp, 32, 8);
            passfactor = Hash.hash(tmp);
        }
        ECKeyPair kp = new ECKeyPair(passfactor, true);

        byte[] salt = new byte[12];
        System.arraycopy(store, 3, salt, 0, 12);
        byte[] derived = SCrypt.generate(kp.getPublic(), salt, 1024, 1, 1, 64);
        byte[] aeskey = new byte[32];
        System.arraycopy(derived, 32, aeskey, 0, 32);

        SecretKeySpec keyspec = new SecretKeySpec(aeskey, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding", "BC");
        cipher.init(Cipher.DECRYPT_MODE, keyspec);

        byte[] encrypted = new byte[16];
        System.arraycopy(store, 23, encrypted, 0, 16);
        byte[] decrypted2 = cipher.doFinal(encrypted);
        for (int i = 0; i < 16; ++i) {
            decrypted2[i] ^= derived[i + 16];
        }

        System.arraycopy(store, 15, encrypted, 0, 8);
        System.arraycopy(decrypted2, 0, encrypted, 8, 8);
        byte[] decrypted1 = cipher.doFinal(encrypted);
        for (int i = 0; i < 16; ++i) {
            decrypted1[i] ^= derived[i];
        }

        byte[] seed = new byte[24];
        System.arraycopy(decrypted1, 0, seed, 0, 16);
        System.arraycopy(decrypted2, 8, seed, 16, 8);
        BigInteger priv = new BigInteger(1, passfactor).multiply(new BigInteger(1, Hash.hash(seed)))
                .remainder(SECNamedCurves.getByName("secp256k1").getN());

        kp = new ECKeyPair(priv, compressed);
        byte[] acs = Hash
                .hash(AddressConverter.toSatoshiStyle(kp.getAddress(), addressFlag).getBytes("US-ASCII"));
        byte[] check = new byte[4];
        System.arraycopy(acs, 0, check, 0, 4);
        if (!Arrays.equals(check, addressHash)) {
            throw new ValidationException("failed to decrpyt");
        }
        return kp;
    } catch (UnsupportedEncodingException e) {
        throw new ValidationException(e);
    } catch (NoSuchAlgorithmException e) {
        throw new ValidationException(e);
    } catch (NoSuchProviderException e) {
        throw new ValidationException(e);
    } catch (NoSuchPaddingException e) {
        throw new ValidationException(e);
    } catch (InvalidKeyException e) {
        throw new ValidationException(e);
    } catch (IllegalBlockSizeException e) {
        throw new ValidationException(e);
    } catch (BadPaddingException e) {
        throw new ValidationException(e);
    }
}

From source file:com.bitsofproof.supernode.api.KeyFormatter.java

License:Apache License

private byte[] bytesBIP38(Key key) throws ValidationException {
    if (passphrase == null) {
        throw new ValidationException("Must have passphrase to encrypt keys");
    }/*from   w ww.  j  a va  2 s  . co m*/
    byte[] store = new byte[43];
    store[0] = 0x01;
    store[1] = 0x42;
    store[2] = key.isCompressed() ? (byte) 0xe0 : (byte) 0xc0;
    byte[] addressHash = new byte[4];
    byte[] aesKey = new byte[32];
    byte[] xor = new byte[32];
    try {
        byte[] ac = Hash
                .hash(AddressConverter.toSatoshiStyle(key.getAddress(), addressFlag).getBytes("US-ASCII"));
        System.arraycopy(ac, 0, addressHash, 0, 4);
        System.arraycopy(ac, 0, store, 3, 4);
        byte[] derived = SCrypt.generate(passphrase.getBytes("UTF-8"), addressHash, 16384, 8, 8, 64);
        System.arraycopy(derived, 32, aesKey, 0, 32);
        System.arraycopy(derived, 0, xor, 0, 32);
    } catch (UnsupportedEncodingException e) {
    }
    SecretKeySpec keyspec = new SecretKeySpec(aesKey, "AES");
    try {
        byte[] priv = key.getPrivate();
        for (int i = 0; i < 32; ++i) {
            priv[i] ^= xor[i];
        }
        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding", "BC");
        cipher.init(Cipher.ENCRYPT_MODE, keyspec);
        byte[] encrypted = cipher.doFinal(priv);
        System.arraycopy(encrypted, 0, store, 7, encrypted.length);
        byte[] cs = Hash.hash(store, 0, 39);
        System.arraycopy(cs, 0, store, 39, 4);
    } catch (NoSuchAlgorithmException e) {
    } catch (NoSuchProviderException e) {
    } catch (NoSuchPaddingException e) {
    } catch (InvalidKeyException e) {
    } catch (IllegalBlockSizeException e) {
    } catch (BadPaddingException e) {
    }
    return store;
}