Back to project page PasswordDroid.
The source code is released under:
GNU General Public License
If you think the Android project PasswordDroid listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package de.wuthoehle.passworddroid.crypto; //from w w w. jav a2s . c om /* Copyright (c) 2015 Marco Huenseler <marcoh.huenseler+git@gmail.com> * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import android.os.Bundle; import android.os.Handler; import android.os.Message; import com.lambdaworks.crypto.SCrypt; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import de.wuthoehle.passworddroid.crypto.SCryptParameters.SCryptParameters; import de.wuthoehle.passworddroid.service.model.entries.DerivatorEntry; import de.wuthoehle.passworddroid.service.model.entries.GetBundleVisitor; import de.wuthoehle.passworddroid.service.model.entries.SaltVisitor; public class DerivationRunnableFactory { public static final int MESSAGE_TYPE_STATUS = 0; public static final int MESSAGE_TYPE_DONE = 1; private byte[] master_key, salts; private SCryptParameters sCryptParameters; private Handler handler; public DerivationRunnableFactory(String master_key, List<String> salts, SCryptParameters sCryptParameters, Handler handler) throws GeneralSecurityException { try { this.master_key = master_key.getBytes("UTF-8"); this.salts = Util.byteListToArray(Util.stringListToUtf8ByteList(salts)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); // This should actually never happen on Android >= 4 // As the passwords have to be generated the same way on every device, we MUST encode // them in UTF-8. Otherwise, we can't calculate a password. throw new GeneralSecurityException("PasswordDerivationTask: No UTF-8!"); } this.sCryptParameters = sCryptParameters; this.handler = handler; } public Runnable getRunnable(final int id, final DerivatorEntry... jobs) { return new Runnable() { @Override public void run() { ArrayList<String> result = new ArrayList<>(); Bundle msgStatusBundle; for (DerivatorEntry entry : jobs) { // Generate final salt try { SaltVisitor visitor = new SaltVisitor(); entry.accept(visitor); byte[] additional_salts = visitor.getSalts(); byte[] all_salts = ByteBuffer.allocate(salts.length + additional_salts.length) .put(salts).put(additional_salts).array(); // TODO Use counter, username, ... byte[] scrypt_seed = SCrypt.scrypt(master_key, all_salts, sCryptParameters.getN(), sCryptParameters.getR(), sCryptParameters.getP(), sCryptParameters.getLen()); AESprng prng = new AESprng( Arrays.copyOfRange(scrypt_seed, 0, 32), Arrays.copyOfRange(scrypt_seed, 32, 40) ); GetBundleVisitor bundleVisitor = new GetBundleVisitor(); entry.accept(bundleVisitor); Bundle passwordProps = bundleVisitor.getBundle(); String characters = passwordProps.getString(GetBundleVisitor.ID_PW_ALL_CHARACTERS); String password = ""; int rand = 0; for (int i = 0; i < passwordProps.getInt(GetBundleVisitor.ID_PW_LENGTH); i++) { do { rand = prng.getInteger(AESprng.bitsForRange(characters.length())); } while (rand >= characters.length()); password += characters.substring(rand, rand + 1); } result.add(password); msgStatusBundle = new Bundle(); msgStatusBundle.putInt("id", id); msgStatusBundle.putInt("type", MESSAGE_TYPE_STATUS); msgStatusBundle.putInt("done", result.size()); msgStatusBundle.putInt("total", jobs.length); sendMessage(msgStatusBundle); } catch (GeneralSecurityException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } // Send results to the calling thread msgStatusBundle = new Bundle(); msgStatusBundle.putInt("id", id); msgStatusBundle.putInt("type", MESSAGE_TYPE_DONE); msgStatusBundle.putStringArrayList("passwordList", result); sendMessage(msgStatusBundle); } }; } private void sendMessage(Bundle content) { Message msgPasswordStatus = handler.obtainMessage(); msgPasswordStatus.setData(content); handler.sendMessage(msgPasswordStatus); } }