出于安全考慮蔓同,有很多鎖屏和輸入pin碼的操作饶辙,在7.0手機(jī)上總是異常,官方也推薦8.0手機(jī)及以上斑粱,所以特意從同事那里借來了8.1的vivo手機(jī)弃揽,能完整地跑起來了,我還是希望能關(guān)注到btc的邏輯则北,尤其是助記詞部分矿微,研究了半天發(fā)現(xiàn)很多邏輯都在BRKeyStore文件的getPhrase里,
public static byte[] getPhrase(final Context context, int requestCode) throws UserNotAuthenticatedException {
Log.d("chendy","getPhrase開始生成助記詞bytes開始 requestCode:"+requestCode);
if (PostAuth.mAuthLoopBugHappened) {
showLoopBugMessage(context);
throw new UserNotAuthenticatedException();
}
AliasObject obj = ALIAS_OBJECT_MAP.get(PHRASE_ALIAS);
byte[] result=getData(context, obj.mAlias, obj.mDatafileName, obj.mIvFileName, requestCode);
Log.d("chendy","getPhrase開始生成助記詞bytes結(jié)束");
return result;
}
但getData方法里大部分都是android的KeyStore尚揣、Cipher之類的系統(tǒng)加密接口涌矢,難道android封裝好了這類加密接口,甚至助記詞都有接口了嗎快骗?不應(yīng)該吧蒿辙,不是要用到bitcoinJ嗎?發(fā)現(xiàn)它還是到本地保存的地方get去了滨巴,也就是在其它地方生成的,那么是在哪里生成的呢俺叭?
public static byte[] retrieveEncryptedData(Context ctx, String name) {
SharedPreferences pref = ctx.getSharedPreferences(KEY_STORE_PREFS_NAME, Context.MODE_PRIVATE);
String base64 = pref.getString(name, null);
Log.d("chendy","retrieveEncryptedData 存在了SharedPreferences里 "+name+" base64:"+base64);
return base64 == null ? null : Base64.decode(base64, Base64.DEFAULT);
}
第一次啟動(dòng)恭取,在滑動(dòng)三張引導(dǎo)頁之后點(diǎn)擊"跳過",會(huì)調(diào)用如下方法熄守,生成賬戶信息蜈垮,并以base64保存起來
public void onCreateWalletAuth(final Context context, boolean authAsked, AuthenticationSuccessListener listener) {
boolean success = WalletsMaster.getInstance().generateRandomSeed(context);
}
整個(gè)的助記詞邏輯都在下面的方法里了,generatePaperKey是jni方法裕照,除了c代碼高效還有能防止算法的反編譯攒发,但開源啊,jni這塊不熟悉啊晋南,另外只能生成12位惠猿,如何生成15位助記詞呢?
public synchronized boolean generateRandomSeed(final Context ctx) {
SecureRandom sr = new SecureRandom();
String languageCode = Locale.getDefault().getLanguage();
Log.d("chendy", "PhraseUtils generateRandomSeed languageCode " + languageCode);//zh
List<String> wordList = Bip39Reader.getBip39Words(ctx, "zh-Hant");
final String[] words = wordList.toArray(new String[wordList.size()]);
final byte[] randomSeed = sr.generateSeed(RANDOM_SEED_LENGTH);
if (words.length != PHRASE_WORDS_LIST_LENGTH) {
BRReportsManager.reportBug(new IllegalArgumentException("the list is wrong, size: " + words.length), true);
return false;
}
if (randomSeed.length != RANDOM_SEED_LENGTH)
throw new NullPointerException("failed to create the seed, seed length is not 128: " + randomSeed.length);
byte[] paperKeyBytes = BRCoreMasterPubKey.generatePaperKey(randomSeed, words);
if (paperKeyBytes == null || paperKeyBytes.length == 0) {
BRReportsManager.reportBug(new NullPointerException("failed to encodeSeed"), true);
return false;
}
for (int i = 0; i < paperKeyBytes.length; i++) {//這兒是字節(jié)
// Log.d("chendy", "paperKeyBytes " + paperKeyBytes[i]);//zh
}
String[] splitPhrase = new String(paperKeyBytes).split(" ");//這兒就是12個(gè)助記詞了
if (splitPhrase.length != PHRASE_LENGTH) {
BRReportsManager.reportBug(new NullPointerException("phrase does not have 12 words:" + splitPhrase.length + ", lang: " + languageCode), true);
return false;
}
for (int i = 0; i < splitPhrase.length; i++) {//這兒就是12個(gè)助記詞了
Log.d("chendy", "splitPhrase " + splitPhrase[i]);//zh
}
Log.d("chendy", "Mnemonic " + WHITESPACE_SPLITTER.splitToList(Arrays.toString(splitPhrase)));//zh
Log.d("chendy", "Mnemonic "+Arrays.toString(splitPhrase).replace(",",""));//zh
return true;
}
下一篇我封裝了java方法负间,可以設(shè)置12位偶妖、15位