public string DecryptedPrivateKeyString(string passphrase) { byte[] decryptedKey = this.DecryptPrivateKeyData(passphrase); if (decryptedKey == null) { //Nothing to decrypt? return(""); } string privateKey; Key key = null; switch (this.PkType) { case PKType.BTC: key = new Key(decryptedKey); privateKey = key.GetWif(Network.Main).ToWif(); break; case PKType.BTC_TestNet: key = new Key(decryptedKey); privateKey = key.GetWif(Network.TestNet).ToWif(); break; // Generic failsafe, no parsing/validation case PKType.UNSET: case PKType.ETH: case PKType.CUSTOM: default: privateKey = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, decryptedKey.AsBuffer()); break; case PKType.Mnemonic: // TODO: Hardcoded to english, can add integrated OS detection or drop down for multilang string[] words = BIP39Helpers.DecodeMnemonicFromEntropy(decryptedKey, Wordlist.English); StringBuilder wordList = new StringBuilder(); foreach (string word in words) { wordList.Append($" {word}"); } privateKey = wordList.ToString(); break; } return(privateKey); }
private void MnemonicProvisionCardButton_Click(object sender, RoutedEventArgs e) { MnemonicErrorLabel.Content = ""; MnemonicKeyLabel.Content = ""; if (Mnemonicpassphrase.Password.Length == 0 || MnemonicpassphraseConfirmation.Password.Length == 0) { MnemonicErrorLabel.Content = "A passphrase was not entered."; return; } if (Mnemonicpassphrase.Password != MnemonicpassphraseConfirmation.Password) { MnemonicErrorLabel.Content = "Passphrases entered did not match."; return; } if (MnemonicEntryTextBox.Text.Length == 0) { MnemonicErrorLabel.Content = "No private key data to store."; return; } if (CardPkType != PKType.Mnemonic) { MnemonicErrorLabel.Content = "Invalid application state. Please restart app."; return; } byte[] privateKeyToEncrypt = null; byte[] publicKeyData = CryptographicBuffer.ConvertStringToBinary("Mnemonic seed backed up.", BinaryStringEncoding.Utf8).ToArray(); try { privateKeyToEncrypt = BIP39Helpers.GenerateEntropyFromWords(MnemonicEntryTextBox.Text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries), NBitcoin.Wordlist.English); } // TODO: Implement better exception types to ease debugging catch (Exception ex) { Logger.Log(ex); MnemonicErrorLabel.Content = "Failed to automatically parse mnemonic phrase."; return; } if (privateKeyToEncrypt.Length > BChipMemoryLayout_BCHIP.PRIVATEKEY_MAX_DATA) { CreateKeyErrorLabel.Content = $"Private key was {PrivateKeyTextBox.Text.Length} bytes, {Math.Abs(PrivateKeyTextBox.Text.Length - BChipMemoryLayout_BCHIP.PRIVATEKEY_MAX_DATA)} bytes over the limit."; return; } string friendlyName = MnemonicFriendlyNameTextBox.Text; ProvisionMnemonicPhraseViewGrid.Dispatcher.BeginInvoke(new Action(() => { ProvisionMnemonicPhraseViewGrid.IsEnabled = false; })); Task.Run(new Action(() => { try { UpdateTextLabel(MnemonicKeyLabel, "Setting up bChip! Do not remove card."); // Encrypt data BChipMemoryLayout_BCHIP bchip = LoadedBChips.SmartCardData as BChipMemoryLayout_BCHIP; bchip.EncryptPrivateKeyData(CardPkType, Mnemonicpassphrase.Password, privateKeyToEncrypt, publicKeyData); bchip.SetFriendlyName(friendlyName); using (var context = _contextFactory.Establish(SCardScope.System)) { using (var isoReader = new IsoReader(context, LoadedBChips.ReaderName, SCardShareMode.Shared, SCardProtocol.Any)) { if (LoadedBChips.AdpuInterface.RequiresInit) { Response initResponse = isoReader.Transmit(LoadedBChips.AdpuInterface.InitCard()); if (initResponse.SW1 != 0x90) { Logger.Log("Error initializing smart card reader"); } } var unlockResponse = isoReader.Transmit(LoadedBChips.AdpuInterface.UnblockCard()); Logger.Log($"ADPU response from pin request: {unlockResponse.StatusWord:X}"); if (unlockResponse.SW1 != 0x90) { UpdateTextLabel(MnemonicKeyLabel, ""); UpdateTextLabel(MnemonicErrorLabel, "Could not be unlock bchip for writing."); return; } var writeResponse = isoReader.Transmit(LoadedBChips.AdpuInterface.WriteCard(bchip)); Logger.Log($"ADPU response from write card data: {unlockResponse.StatusWord:X}"); if (writeResponse.SW1 != 0x90) { UpdateTextLabel(MnemonicKeyLabel, ""); UpdateTextLabel(MnemonicErrorLabel, "Failure writing data to the bchip."); return; } } } UpdateTextLabel(MnemonicKeyLabel, string.Empty); ClearTextBox(MnemonicFriendlyNameTextBox); // Done? clear loaded card, reload card LoadedBChips = null; ScanAndLoadConnectedCards(); } catch (Exception ex) { Logger.Log(ex); } finally { ProvisionMnemonicPhraseViewGrid.Dispatcher.BeginInvoke(new Action(() => { ProvisionMnemonicPhraseViewGrid.IsEnabled = true; })); } })); }