Private-Key

如何恢復我的私鑰失去的一端?

  • September 25, 2020

我在我的舊東西中發現了這張紙。你能用它做什麼?有什麼辦法可以填補缺失的部分嗎?

在此處輸入圖像描述

TL; 博士:

您不需要在這裡(至少幾乎)暴力破解任何內容,並且可以使用簡單的 Python 腳本在不到 1 秒的時間內在家中的普通 PC 上恢復失去的最後 7 個字元!

詳細地:

在您的圖片中,私鑰末尾**缺少 7 個字元(**通過與使用相同 HTML 文件的測試列印輸出進行比較得出)。

是的,這種密鑰格式使用Base58字母是正確的,因此每個字元有 58 種可能性,因此對於 7 個字元,您需要在理論上嘗試58^7可能性(大約 2 萬億),但是所有這些考慮都缺少一個重要的事實:

當這樣的私鑰(格式稱為WIF縮寫Wallet Import Format,另請參閱此處的參考文件)被編碼時,最後(在實際私鑰之後)添加 4 個字節作為校驗和。因此,如果這 4 個字節缺失(最後),您可以從其餘字節中計算出來。

第二:在您的圖片中,您的私鑰似乎以L. 這表明比特幣地址是基於壓縮的公鑰。不用擔心,這是一個技術細節,但這可以進一步幫助您:壓縮公鑰的私鑰在密鑰之後(校驗和之前)添加了另一個特殊字節,即固定0x01(另請參見WIF 的參考文件) .

這意味著 WIF 編碼私鑰的最後 5 個字節(以Lor開頭K)要麼是靜態的,要麼可以從其餘部分計算出來。

所以你很幸運最後7 個字元失去了(而不是7 個,因為那樣你真的需要暴力破解 2 萬億種可能性)。

如何處理這些資訊:

如果我們現在將這些知識應用於 base58,我們會看到只有一個字元失去,然後我們可以計算其餘字元。

推理:首先:單個 base58 字元攜帶 ~5.85799 = log2(58) 位資訊,其次:我們不需要最後 40 位(4 字節校驗和 + 1 個壓縮密鑰的靜態字節為 5 字節 = 40 位)。

因此,如果最後 ( 6 * 5.85799.. = 35.14794) 只缺少 6 個字元,我們就不需要暴力破解任何東西,因為這仍然少於我們不需要的 40 位。

結論:

由於您缺少 7 個字元,我們只需要暴力破解一個字元(這意味著只需 58 次嘗試,而不是 2 萬億次)。所以我們只是嘗試添加 bas58 字母表中的 58 個字元之一。對於每次嘗試,我們通過添加靜態壓縮密鑰標誌字節 () 來計算完整的 base58 字元串,0x01然後是校驗和,並簡單地將其與您擁有的其餘密鑰進行比較。如果匹配,則為有效候選人。

在這 58 次嘗試結束時,您最終會得到 2 或 3 個(最多)有效的候選私鑰,只需檢查這 3 個密鑰,看看哪一個屬於您的地址。

Reddit 使用者/u/dooglus/ (不是我)在他對您的文章的評論中首先指出了這一點,他還添加了一段 Python 程式碼,它與我上面描述的完全一樣。

不要相信任何人,不要把你的鑰匙交給任何陌生人!

現在慢慢來,了解下面的 Python 腳本做了什麼(不要相信我或任何陌生人),當你覺得安全時,從/u/dooglus/的評論中複製 Python 片段,將其保存在一個名為的文本文件中complete-wif.py在安全的電腦上。之後使電腦離線並通過在命令行中鍵入以下內容來執行 Python 腳本:

python3 complete-wif.py L...-your-private-key-goes-here...yhub

它將在不到 1 秒的時間內列印 2 或 3 個完整的 WIF 私鑰

附錄:

作為參考,我附加了 Python 腳本,但這不是我的工作,所有學分都歸 /u/dooglus/。我只是可以確認它執行了我上面描述的操作(但請其他人確認這一點並嘗試使用其他私鑰,然後再使用您的真實私鑰信任它):

#!/usr/bin/env python3

import base58, sys

partial = sys.argv[1]

if len(partial) != 45:
   print("partial key should be 45 characters")
   sys.exit(1)

results = {}
for c in '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz':
   wif = base58.b58encode_check(base58.b58decode(partial + c*7)[:33] + b'\x01').decode('ascii')
   if wif[:45] == partial: results[wif] = True

for k in results.keys(): print(k)

它必須是蠻力的。有幾種方法,但基本上它是用 base-58 字元替換每個字元並檢查密鑰。

該過程所需的時間取決於失去的字元數,並略微取決於密鑰是壓縮還是未壓縮,還有一點取決於您的運氣。

但是,如果您的密鑰已壓縮並且最多缺少 11 個字元,或者未壓縮並且從其末尾最多缺少 9 個字元(從您的螢幕截圖中似乎就是這種情況),則可以在幾秒鐘內恢復。

查看GitHub 上的FinderOuter。Missing Base58 選項處理您的情況。您必須輸入已有的字元並用特殊字元替換缺少的字元,*然後在第二個框中輸入您的地址並點擊Find

全面披露:我是 The FinderOuter 的開發者。

PS 發布的版本(0.4.1)比較老,沒有上面提到的優化,你得自己編譯程式碼或者等待0.5.0。

編輯:版本 0.5.0 於 2020-09-17 發布,可以恢復這種特殊情況,最多可從末尾失去 11 個字元。

引用自:https://bitcoin.stackexchange.com/questions/98944