本文由chihao翻譯,譯文以CC0釋出。原文為《How the Catalan government uses IPFS to sidestep Spain’s legal block》。原文在《黑客新聞》上的討論串在這裡。
来源: https://medium.com/@chihaoyo
正文以巴塞隆納為首府的加泰隆尼亞,是西班牙現行十七個自治社群之一。加泰隆尼亞獨立運動歷史久長,過去也曾宣布獨立。現在,多數加泰隆尼亞人希望舉行獨立公投,支持獨立人數也不容小覷,政治氣氛熱烈,不在話下。
架設在行星檔案系統上的網站
透過行星檔案系統(Interplanetary File System)的網域
https://ipfs.io/
發佈這個投票資訊網站,有幾個好處。- 西班牙政府很難強制要求將造訪國際頂級網域
.io
的訪客重新導向別的網站。如果是加泰隆尼亞的.cat
網域結尾的網站,這就很容易了。 - 網域擁有者與「加獨份子」扯不上關係。這讓任何干預行動很難取得法律正當性,尤其是當
.io
網域的管理在英國境內,而這些行動必須在英國境內執行時。 - 因為這是一個
https
網站,這讓從網路服務供應商進行中間人攻擊變的困難。政府還是可以要求網路服務供應商封鎖任何來自或前往ipfs.io
的網路通訊,但沒辦法讓使用者在不被瀏覽器警告憑證失效的狀況下,看到其他政府置入的內容。 - 就算西班牙政府封鎖任何與
ipfs.io
的網路通訊,網站上的資訊還是能被存取、複製。ipfs.io
只是行星檔案系統的一個代理服務,行星檔案系統本身是點對點、分散式、內容即位址的網路檔案系統。只要下載行星檔案系統的程式,任何人都可以存取系統中的任何內容。
點對點、分散式讓內容能夠自由擴散,當內容能自由擴散,它就幾乎不可能被單一用戶封鎖。點對點的加密連線也讓存取內容的用戶很難被認出來,也許中國可以,但西班牙鐵定是不行的。
問題:可以嗎?
內容即位址讓內容無法被竄改。加泰隆尼亞政府人員只要分享網站首頁的雜湊值(hash),所有人都能確定點擊連結後看到的內容確實是加泰政府所發佈的。
一個挑戰:因為行星檔案系統上的資訊都是公開的,所以網站使用、連結的資訊頁都必須是公開的。只要需要額外的伺服器處理私密的資料,那這個伺服器就很有可能成為讓整件事失敗的弱點。
所以,加泰隆尼亞政府必須讓網站的資料庫成為能夠透過行星檔案系統擴散、能簡單地用網址,或最少的程式碼,就能查詢的資料庫。他們是怎麼做到的?
靜態資料庫
以往的選舉,西班牙公民需要在政府網站上輸入身分證字號、生日、現居地郵遞區號。核對無誤後,網站才會告訴你該去哪裡投票。
這個做法顯然不怎麼樣,因為如果你知道某人的生日,還有他現在住在哪個區域,就可以透過不停嘗試身分證字號組合得到你想要的資訊。不過,如果是一般的網站,只要在伺服器上控制單一IP每秒存取次數就可以解決。
不過這次不同,加泰隆尼亞不能使用伺服器,否則西班牙政府就能輕易封鎖伺服器。為了充分利用行星檔案系統的優勢,整個網站,連同資料庫都必須是靜態的,這樣內容才能自由擴散。
來看看他們怎麼讓選民查詢投票資訊吧!在網站中《我要去哪裡投票》這一頁,介面會請你輸入這些。
- 身分證字號(DNI)後五碼數字,加上一個字母檢核碼,格式是
[0–9]{5}[A-Z]
- 出生年月日,格式是
YYYYMMDD
- 郵遞區號五碼,皆為數字,格式是
[0–9]{5}
這十八碼,就是能夠取得個人投票資訊
🗳
的個人鑰匙👤
。身分證字號 + 生日 + 郵遞區號 → 👤 → lookup()
→ 🗳
可是可是,如果這些個人鑰匙
👤
也都是用明碼發佈,那豈不是洩露了所有加泰隆尼亞公民的個資嗎?加密來救援
為了易於了解,將個人對應到投票資訊的資料庫查詢程式
lookup()
大概長成這樣。function lookup(dni, birth, zip, callback) { var key = dni + birth + zip; var passkey = sha256_times(key, 1714); var search = sha256(passkey);
var dir = search.substring(0, 2); var file = search.substring(2, 4); var path = db_path + dir + "/" + file + ".db"; var lines = readfile(path).split("\n");
lines.forEach(function(line) { if (line.substring(0,60) == search.substring(4)) { found = true;
var plaintext = decrypt(line.substring(60), passkey); callback(plaintext.split('#')); } })
if (!found) { callback("not-found"); }}
裡面有用到三個加密函式,分別是第三行的
sha256
、第四行的sha256_times
和第十五行的decrypt
。三個函式的細節如下,其中在第二行、第十六行使用的crypto
就是Node.js的crypto
模組,任何人都可以取得、使用。function sha256(text) { return crypto.createHash('sha256') .update(text) .digest('hex');}
function sha256_times(text, times) { var result = text; for (var x = 0; x < times; x++) { result = sha256(result); } return result;}
function decrypt(text, key) { var decipher = crypto.createDecipher('aes-256-cbc', key); var dec = decipher.update(text, 'hex', 'utf8'); dec += decipher.final('utf8'); return dec;}
這其實沒有很複雜。
lookup()
這個函式在第二行把身分證字號、生日、郵遞區號所組成的個人鑰匙👤
用sha256
這個函式加密1714次,生成解密密碼🎛
,在第三行再用sha256
一次,把解密密碼再次加密,成為查詢金鑰🔑
。👤 →sha256
× 1714 → 🎛 →sha256
→ 🔑
接下來,就用查詢金鑰
🔑
查詢資料庫🗄
,找到一或多筆相對應的內容之後,再用解密密碼🎛
將找到的內容解密,進而獲得投票資訊🗳
。🔑 → 🗄 → 加密的投票資訊 → 🎛 → 🗳
我不是什麼加密專家,看不出來這樣的機制有沒有什麼致命的失誤。不過,要強制取得個人資訊,看樣子除了暴力解,好像也沒別招了。那麼,到底要多暴力呢?讓我們賣弄一下自己的教育程度,估計看看。
- 身分證字號的部分,因為最後的檢核字母只有二十三種可能,所以總共有10⁵×23種可能的組合。
- 出生年月日的部分,假設沒有人超過一百歲,就有365×100種可能。
- 郵遞區號的部分,因為西班牙的郵遞區號是由兩位省的代碼加上三位區碼組成,如果假設所有人都住在加泰隆尼亞,而加泰隆尼亞境內僅有四省,所以有4×10³種可能。不過,並不是所有可能的組合都是有效的郵遞區號,而且任何人都可以輕易取得所有有效郵遞區號的列表。在這裡,暫時不考慮這件事,先這樣。
- 把所有可能綜合考慮,個人鑰匙
👤
有10¹⁰×23×365×4,也就是33580×10¹⁰種組合,大概是48 bit。
「怎麼這麼少?」算完之後,我懷疑只要有點耐心,有一點錢,應該能很快把整個資料庫轉為明碼。假設需要計算1715次
sha256
來確認某個人鑰匙👤
在資料庫裡有沒有資料,那麼,那麼檢查完所有可能的個人鑰匙👤
就需要計算575897×10¹²次雜湊值。參考比特幣維基,用不同的硬體設備所需的時間如下。- AntMiner S9每秒能計算28×10⁹次雜湊值,所以檢查完所有可能的個人鑰匙
👤
,需要238天。 - AMD 7970每秒825×10³,需要20870年。
- Nvidia Tesla S2070每秒749×10³,需要24381年。
嗯。對一個普通駭客來說不太可行,但如果有點錢,絕對不是不可能。並且,這是要把整個資料庫轉為明碼需要的時間,如果你知道某人的身分證字號和住處,用你的筆電猜測他的生日,應該不會花上多少時間吧!
未解的問題
雖然困難,不過把整個資料庫轉為明碼是可能的。這就表示加泰隆尼亞政府或許洩露了所有加泰隆尼亞公民的部分身分證字號、生日、郵遞區號及投票地點。因為西班牙的身分證字號並不是什麼秘密資訊,所以也許這些資訊也沒那麼重要,但如果頻繁使用這種作法,尤其是當有人開始交叉比對資料庫時,事情可能就不這麼無害了。
每個黑客都應該知道的事:絕對不要自己寫加密演算法。加泰隆尼亞政府的黑客是否犯了這個錯誤?希望五樓能為我解答。
最後,行星檔案系統大致上保證內容的可及,但據我所知,它並不保證匿名。西班牙政府已經對複製這個網站內容的至少十人提出告訴,他們也能很容易的,在行星檔案系統中架一個受污染的節點,秘密紀錄存取的IP位址,就能起訴使用者。
那麼,你覺得加泰隆尼亞的作法如何?如果是你的話,會怎麼做?對於想要避免國家言論審查的人,這樣的作法夠不夠嚴謹?
加泰隆尼亞的黑客們,現在一定很興奮吧?
没有评论:
发表评论