SMS 訊息是最受歡迎的雙重認證 (2FA) 方法。 它被銀行、電子錢包、加密錢包、郵箱和各種服務使用;
我對這種情況感到憤慨,因為這種方法不安全。 將號碼從一張 SIM 卡重新分配到另一張 SIM 卡的做法始於行動時代之初——這就是當 SIM 卡遺失時恢復號碼的方法。 「數位貨幣竊盜專家」意識到「重寫 SIM 卡」選項可用於詐欺計畫。 畢竟誰控制了SIM卡,誰就可以控制別人的網路銀行、電子錢包,甚至是加密貨幣。 您也可以透過賄賂電信員工、使用欺騙或偽造文件來佔有他人的號碼。
數千起 SIM 卡交換事件已被揭露,這項詐騙計畫被稱為「SIM 卡交換」。 災難的規模表明世界很快就會放棄透過簡訊實現的 2FA。 但這並沒有發生 - 在
我們建議使用安全的 2FA 方法,透過區塊鏈傳送一次性程式碼,我們將告訴您服務所有者如何連接它。
計數達到數百萬
據倫敦警方稱,2019 年 SIM 交換詐欺增加了 63%,攻擊者的「平均帳單」為 4,000 英鎊。 我沒有在俄羅斯找到任何統計數據,但我認為它們更糟。
SIM 交換被用來竊取流行的 Twitter、Instagram、Facebook、VK 帳戶、銀行帳戶,最近甚至還竊取加密貨幣 -
XNUMX 月,美國密西根州東區檢察官辦公室
喬爾·奧爾蒂斯在大學新聞發布會上的照片。 兩年後,他因網路詐騙而被拘留。
SIM 卡交換的工作原理
「交換」就是交換的意思。 在所有此類計劃中,犯罪分子通常會透過重新發行 SIM 卡來獲取受害者的電話號碼,並用它來重設密碼。 理論上,典型的 SIM 卡交換如下:
- 情報服務。 詐騙者會找出受害者的個人資訊:姓名和電話號碼。 它們可以在開源(社群網路、朋友)中找到,也可以從共犯(行動電信商的員工)收到。
- 阻塞。 受害者的SIM卡已停用; 為此,只需致電提供者的技術支持,提供號碼並說明手機遺失即可。
- 捕獲號碼,將其轉移到您的 SIM 卡。 通常,這也是透過電信公司的同謀或透過偽造文件來完成的。
在現實生活中,情況甚至更為嚴重。 攻擊者選擇一個受害者,然後每天追蹤手機的位置——一次請求接收用戶已切換到漫遊的訊息的費用為 1-2 美分。 當SIM卡的主人出國後,他們就與通訊商店的經理協商發放新的SIM卡。 它的費用約為 50 美元(我找到了資訊 - 在不同的國家和不同的運營商,從 20 美元到 100 美元不等),最壞的情況是經理將被解僱 - 對此沒有任何責任。
現在,所有短信都會被攻擊者收到,而手機的所有者將無法對此採取任何措施 - 他在國外。 然後,惡棍可以存取所有受害者的帳戶,並根據需要更改密碼。
返還被盜財產的機會
銀行有時會向受害者妥協,並從他們的帳戶中提取轉帳。 因此,即使沒有找到罪犯,也可以退還法定貨幣。 但有了加密貨幣錢包,一切就變得更加複雜——而且 技術上,並立法。 到目前為止,還沒有一家交易所/錢包向交換受害者支付賠償金。
如果受害者想在法庭上捍衛自己的資金,他們就會責怪運營商:他為帳戶資金被盜創造了條件。 這正是我所做的
到目前為止,還沒有哪個州制定了合法保護加密貨幣所有者的工作計劃。 您無法為您的資金投保或獲得損失賠償。 因此,防止交換攻擊比處理其後果更容易。 最明顯的方法是為 2FA 使用更可靠的「第二因素」。
SIM 交換並不是透過簡訊進行 2FA 的唯一問題
從技術角度來看,簡訊中的確認碼也是不安全的。 由於 7 號訊號系統 (SS7) 中未修補的漏洞,訊息可能會被攔截。 SMS 上的 2FA 被官方認為是不安全的(美國國家標準與技術研究所在其報告中表示這一點)
同時,2FA的存在往往會給使用者一種虛假的安全感,他會選擇更簡單的密碼。 因此,這種身份驗證不會增加難度,反而使攻擊者更容易獲得帳戶的存取權限。
而且簡訊通常會延遲很長時間才能到達,或者根本不會到達。
其他 2FA 方法
當然,光芒並沒有集中在智慧型手機和簡訊上。 2FA 還有其他方法。 例如,一次性 TAN 代碼:一種原始方法,但它有效 - 一些銀行仍在使用它。 有些系統使用生物辨識資料:指紋、視網膜掃描。 就便利性、可靠性和價格而言,另一個似乎是合理折衷的選擇是 2FA 的特殊應用程式:RSA 令牌、Google Authenticator。 還有物理按鍵等方法。
從理論上講,一切看起來都是合乎邏輯且可靠的。 但在實務中,現代 2FA 解決方案存在問題,並且正因為這些問題,現實與預期有所不同。
根據
使用者將許多 2FA 方法與擔心失去存取權連結在一起。 實體鑰匙或 TAN 密碼清單可能會遺失或被盜。 我個人在使用 Google Authenticator 時有過不好的經驗。 我的第一部裝有此應用程式的智慧型手機壞了 - 感謝我為恢復帳戶訪問所做的努力。 另一個問題是切換到新設備。 由於安全原因,Google Authenticator 沒有匯出選項(如果可以匯出金鑰,那還有什麼安全性?)。 有一次我手動攜帶鑰匙,然後我決定將舊智慧型手機放在架子上的盒子裡更容易。
2FA 方法應該是:
- 安全 - 只有您而不是攻擊者才能存取您的帳戶
- 可靠 - 您可以在需要時隨時存取您的帳戶
- 方便且易於使用 - 使用 2FA 非常清晰且花費最少的時間
- 便宜的
我們相信區塊鏈是正確的解決方案。
在區塊鏈上使用 2FA
對於用戶來說,區塊鏈上的 2FA 看起來與透過簡訊接收一次性代碼相同。 唯一的區別是交付管道。 取得 2FA 程式碼的方法取決於區塊鏈提供的內容。 在我們的專案中(資訊在我的個人資料中),這是一個 Web 應用程式、Tor、iOS、Android、Linux、Windows、MacOS。
該服務產生一次性代碼並將其發送到區塊鏈上的信使。 然後按照經典:使用者在服務介面輸入收到的代碼並登入。
在文章中
- 一鍵建立帳戶 - 無需電話或電子郵件。
- 所有帶有 2FA 代碼的訊息均經過端對端 curve25519xsalsa20poly1305 加密。
- 排除 MITM 攻擊 - 每條帶有 2FA 代碼的訊息都是區塊鏈上的一筆交易,並由 Ed25519 EdDSA 簽署。
- 帶有 2FA 代碼的訊息最終位於其自己的區塊中。 區塊的順序和時間戳無法更正,因此訊息的順序也無法更正。
- 沒有中央結構來檢查訊息的「真實性」。 這是由基於共識的分散式節點系統完成的,並由使用者擁有。
- 無法停用 - 無法封鎖帳戶且無法刪除訊息。
- 隨時從任何裝置存取 2FA 代碼。
- 使用 2FA 代碼確認訊息傳遞。 發送一次性密碼的服務確信它已被傳送。 沒有“再次發送”按鈕。
為了與其他一些2FA方法進行比較,我做了一個表格:
用戶在區塊鏈信使中收到一個帳戶,即可在一秒鐘內接收代碼 - 只需使用密碼即可登入。 因此,申請方法可能會有所不同:您可以使用一個帳戶接收所有服務的代碼,也可以為每項服務建立單獨的帳戶。
還有一個不便之處——帳戶必須至少有一筆交易。 為了讓用戶接收帶有程式碼的加密訊息,您需要知道他的公鑰,並且它僅在第一筆交易時出現在區塊鏈中。 這就是我們設法擺脫困境的方法:我們讓他們有機會在錢包中接收免費代幣。 然而,更好的解決方案是將帳戶命名為公鑰。 (為了比較,我們有一個帳號 U1467838112172792705 是公鑰的衍生物 cc1ca549413b942029c4742a6e6ed69767c325f8d989f7e4b71ad82a164c2ada。 對於信使來說,這更方便和可讀,但對於發送 2FA 代碼的系統來說,這是一個限制)。 我想,未來會有人做出這樣的決定,把「方便、可達」搬到綠區。
發送 2FA 代碼的價格非常低 - 0.001 ADM,現在是 0.00001 USD。 同樣,你可以提高你的區塊鏈並使價格為零。
如何將區塊鏈上的 2FA 連接到您的服務
我希望我能引起一些讀者的興趣,將區塊鏈授權添加到他們的服務中。
我會以我們的Messenger為例告訴你如何做到這一點,以此類推,你可以使用另一個區塊鏈。 在 2FA 演示應用程式中,我們使用 postgresql10 來儲存帳戶資訊。
連接階段:
- 在區塊鏈上建立一個帳戶,您將從中發送 2FA 代碼。 您將收到一個密碼,該密碼用作私鑰,用於使用代碼加密訊息並簽署交易。
- 將腳本新增至您的伺服器以產生 2FA 程式碼。 如果您已使用任何其他具有一次性密碼傳送的 2FA 方法,則您已完成此步驟。
- 將腳本新增至您的伺服器,將程式碼傳送給區塊鏈信使中的使用者。
- 建立用於發送和輸入 2FA 代碼的使用者介面。 如果您已使用任何其他具有一次性密碼傳送的 2FA 方法,則您已完成此步驟。
1 帳戶創建
在區塊鏈中創建帳戶意味著產生私鑰、公鑰和派生帳戶地址。
首先,產生 BIP39 密碼,並根據它計算 SHA-256 雜湊值。 該哈希用於生成私鑰ks和公鑰kp。 根據公鑰,使用相同的 SHA-256 進行反轉,我們獲得了區塊鏈中的位址。
如果您想每次從新帳戶發送 2FA 代碼,則需要將帳戶建立代碼新增至伺服器:
import Mnemonic from 'bitcore-mnemonic'
this.passphrase = new Mnemonic(Mnemonic.Words.ENGLISH).toString()
…
import * as bip39 from 'bip39'
import crypto from 'crypto'
adamant.createPassphraseHash = function (passphrase) {
const seedHex = bip39.mnemonicToSeedSync(passphrase).toString('hex')
return crypto.createHash('sha256').update(seedHex, 'hex').digest()
}
…
import sodium from 'sodium-browserify-tweetnacl'
adamant.makeKeypair = function (hash) {
var keypair = sodium.crypto_sign_seed_keypair(hash)
return {
publicKey: keypair.publicKey,
privateKey: keypair.secretKey
}
}
…
import crypto from 'crypto'
adamant.getAddressFromPublicKey = function (publicKey) {
const publicKeyHash = crypto.createHash('sha256').update(publicKey, 'hex').digest()
const temp = Buffer.alloc(8)
for (var i = 0; i < 8; i++) {
temp[i] = publicKeyHash[7 - i]
}
return 'U' + bignum.fromBuffer(temp).toString()
}
在演示應用程式中,我們對其進行了簡化 - 我們在 Web 應用程式中建立了一個帳戶,並從中發送程式碼。 在大多數情況下,這對用戶來說也更方便:他知道服務從特定帳戶發送 2FA 代碼並可以命名它。
2 產生2FA代碼
必須為每個使用者登入產生 2FA 代碼。 我們使用圖書館
const hotp = speakeasy.hotp({
counter,
secret: account.seSecretAscii,
});
檢查使用者輸入的2FA代碼的有效性:
se2faVerified = speakeasy.hotp.verify({
counter: this.seCounter,
secret: this.seSecretAscii,
token: hotp,
});
3 發送 2FA 代碼
您可以使用區塊鏈節點API、JS API庫或控制台提交2FA程式碼。 在此範例中,我們使用控制台 - 這是命令列介面,這是一個簡化與區塊鏈互動的實用程式。 要傳送帶有 2FA 代碼的訊息,您需要使用以下命令 send message
控制台。
const util = require('util');
const exec = util.promisify(require('child_process').exec);
…
const command = `adm send message ${adamantAddress} "2FA code: ${hotp}"`;
let { error, stdout, stderr } = await exec(command);
發送訊息的另一種方法是使用以下方法 send
在 JS API 庫中。
4 使用者介面
需要為使用者提供輸入 2FA 代碼的選項,這可以根據您的應用程式平台以不同的方式完成。 在我們的範例中,這是 Vue。
區塊鏈雙重認證演示應用程式的源代碼可以查看
來源: www.habr.com