首稿件發(fā)在了先知社區(qū)中恋捆,由于原創(chuàng)稿件东亦,所以我在之后引用到自己的博客中
原文鏈接為 https://xz.aliyun.com/t/2874
一、引言
提及區(qū)塊鏈我們不得不想到“幣圈”的那些事情轧膘。而提到數(shù)字貨幣我們又不得不感嘆一下數(shù)字貨幣的優(yōu)點(diǎn)之一——匿名性。對此兔甘,我從一下四個點(diǎn)進(jìn)行切入谎碍,逐一為大家介紹“幣圈”里關(guān)于“匿名”的是是非非。
- 比特幣的匿名性
- 關(guān)于匿名性的CoinJoin方案
- Zcash中的匿名性
- 我們所未曾熟悉的“門羅幣”
下面就請跟隨我的文章洞焙,一點(diǎn)一點(diǎn)進(jìn)入密碼學(xué)與區(qū)塊鏈中蟆淀,來了解屬于BlockChain的點(diǎn)點(diǎn)滴滴。
二澡匪、比特幣的匿名性
1 比特幣的地址與交易
眾所周知熔任,前一段時間發(fā)生的全國高校勒索病毒就是希望使用比特幣作為勒索贖金。而為什么在這里使用比特幣來代替現(xiàn)實(shí)中的直接轉(zhuǎn)賬呢唁情?這里我們就可以提到比特幣匿名性的優(yōu)點(diǎn)了疑苔。
簡單來說,比特幣地址是一串由字母和數(shù)字組成的26位到34位字符串甸鸟,看起來有些像亂碼惦费。通過區(qū)塊鏈可以查到每個比特幣地址的所有轉(zhuǎn)賬記錄。比特幣地址就是個人的比特幣賬戶抢韭,相當(dāng)于你的銀行卡卡號薪贫,任何人都可以通過你的比特幣地址給你轉(zhuǎn)賬比特幣。
比特幣地址是比特幣網(wǎng)絡(luò)中的ID或者賬號刻恭,用于接收比特幣瞧省。它就是一串符號,以1或3開頭鳍贾,包含27到34個數(shù)字或字母(不包括0鞍匾, I), 例如:14qViLJfdGaP4EeHnDyJbEGQysnCpwn1gZ骑科。比特幣地址來源于密碼學(xué)中的公鑰加密橡淑。用戶首先創(chuàng)建一個密鑰對,它包括一個私鑰以及由其衍生出的公鑰纵散。對公鑰進(jìn)行進(jìn)一步運(yùn)算梳码,可得到比特幣的地址隐圾;而私鑰本質(zhì)是一個隨機(jī)數(shù),用于比特幣轉(zhuǎn)賬時的交易簽名掰茶。比特幣交易中所說的消費(fèi)暇藏,指的是轉(zhuǎn)移一 筆以前交易的比特幣,給以比特幣地址所標(biāo)識的新所有者濒蒋。一個典型的Alice向Bob轉(zhuǎn)賬比特幣的場景是:Alice創(chuàng)建一筆交易盐碱,她首先用自己的私鑰進(jìn)行數(shù)字簽名,表明自己對要轉(zhuǎn)出的比特幣擁有所有權(quán)沪伙,同時發(fā)出一個鎖定“聲明”——只有Bob的簽名才可以拿出這筆比特幣瓮顽。隨后,這筆交易被傳送到比特幣網(wǎng)絡(luò)當(dāng)中围橡,成為區(qū)塊鏈眾多區(qū)塊的一部分暖混。從Bob的視角來看,他可以驗證出Alice確實(shí)有這筆比特幣的擁有權(quán)翁授,同時使用自己的簽名可以確認(rèn)拣播,這是一筆發(fā)給自己的收入支付。上述是比特幣地址的密碼學(xué)原理收擦。
根據(jù)上述內(nèi)容我們不難發(fā)現(xiàn)贮配,比特幣中所使用的“地址”并不是公開、易懂的簡單地址塞赂。而是利用了密碼學(xué)中非對稱密碼的算法泪勒。這樣做可以將那些明文的地址轉(zhuǎn)換為匿名性更強(qiáng)的地址。起到混淆的作用宴猾,也使公眾無法直接查看到地址所屬的用戶圆存。
具體來說,比特幣的地址是如何生成的鳍置?它又有什么特點(diǎn)呢辽剧?首先我們要講解一下比特幣錢包地址的生成送淆。
當(dāng)用戶加入?yún)^(qū)塊鏈這個大家族的時候税产,“地址”就必不可缺。
1偷崩,首先用戶會使用算法隨機(jī)生成一個【私鑰】辟拷,而這個私鑰一般為256bit。由于私鑰十分重要阐斜,所以用戶也會將私鑰安全的保存起來衫冻。
2,之后我們會使用SECP256K1算法將私鑰處理生成【公鑰】谒出。(SECP256K1是一種橢圓曲線算法隅俘,通過一個已知『私鑰』時可以算得『公鑰』邻奠,而『公鑰』已知時卻無法反向計算出『私鑰』。這是保障比特幣安全的算法基礎(chǔ)为居。)
3碌宴,使用哈希算法RIPEMD160對公鑰進(jìn)行處理得到【公鑰哈希】蒙畴。(由于哈希函數(shù)的特性贰镣,此算法也是不可逆的)
4,將一個字節(jié)的地址版本號連接到『公鑰哈仙拍』頭部(對于比特幣網(wǎng)絡(luò)的pubkey地址碑隆,這一字節(jié)為“0”),然后對其進(jìn)行兩次SHA256運(yùn)算蹬音,將結(jié)果的前4字節(jié)作為『公鑰哈仙厦海』的校驗值,連接在其尾部著淆。
5楼入,將上一步結(jié)果使用BASE58進(jìn)行編碼(比特幣定制版本),就得到了『錢包地址』牧抽。
具體格式可參考文章神秘的比特幣地址詳解
由此我們得到如下圖嘉熊。
雖然我們不知道交易雙方的具體地址,但是我們有上述生成的字符串地址也可以進(jìn)行相關(guān)交易扬舒。
- 首先我們需要使用【私鑰】對交易進(jìn)行簽名阐肤。
由于私鑰是交易發(fā)起方所保存的,所以我需要利用私鑰對我們的交易進(jìn)行簽名讲坎,用以證明是我本人發(fā)起的交易孕惜。
- 之后要將其【公鑰】一并寫入到交易中便于他人驗證。
交易數(shù)據(jù)被廣播到比特幣網(wǎng)絡(luò)后晨炕,節(jié)點(diǎn)會對這個交易數(shù)據(jù)進(jìn)行檢驗衫画,其中就包括對簽名的校驗。如果校驗正確瓮栗,那么這筆余額就成功地從“轉(zhuǎn)出錢包”轉(zhuǎn)移到“轉(zhuǎn)入錢包”了削罩。
2 比特幣半匿名性
而有心的讀者也已經(jīng)發(fā)現(xiàn),雖然比特幣中使用了非對稱加密算法费奸,但是我的交易仍會被所有節(jié)點(diǎn)所查看弥激。而研究表明,比特幣可仍然可以通過那些看似隨機(jī)組成的字符串來找到交易的發(fā)起方和接收方愿阐∥⒎可參考
比特幣匿名性其實(shí)有跡可循找到“身份標(biāo)示點(diǎn)”可輕易鎖定目標(biāo)
于是我們可以大膽的說,比特幣是具有“半匿名性”的數(shù)字貨幣缨历。
除了匿名性外以蕴,每個地址的隱私性幾乎也是無法保證的糙麦。因為比特幣的每一筆交易都會公開記錄在區(qū)塊鏈賬本上,任何人都可以查閱丛肮。只要通過分析每個地址發(fā)生過的交易喳资,就可以發(fā)現(xiàn)很多賬號之間的關(guān)系。
比特幣的交易是記錄各個地址之間轉(zhuǎn)移貨幣的數(shù)量腾供,并且通常有一個或多個地址輸入仆邓,對應(yīng)一個或多個地址的輸出。例如:A要支付10個比特幣給B伴鳖,而A具有3個地址节值,各有4個比特幣(4+4+4 否則不夠用)。不僅如此榜聂,當(dāng)A給B轉(zhuǎn)賬后搞疗,A仍然需要找零的過程。
而這個交易會廣播到所有節(jié)點(diǎn)并被保存下來须肆。其他人可以根據(jù)此來推斷A的初始地址與找零后地址的關(guān)系匿乃。不論A經(jīng)過了多少次交易,生成了多少次地址豌汇。那我只要擁有系統(tǒng)中所有的交易記錄就可以溯源找到你本來的A幢炸。
而下面,我們將針對這些半匿名性問題提出一些改進(jìn)算法拒贱。
三宛徊、CoinJoin方案
CoinJoin原理相對比較簡單,就是把不同用戶的多個交易合并成一個交易逻澳。
外人從這種混淆過的交易中無法假定輸入地址屬于同一人所有闸天,也不能確定貨幣的流向。用戶可以進(jìn)行多次CoinJoin操作斜做,進(jìn)一步隱藏交易的關(guān)系苞氮。
上述圖片表示了原本比特幣轉(zhuǎn)賬交易的簡圖。而下面我們表示一下CoinJoin的具體方法瓤逼。
CoinJoin不需要改變比特幣的協(xié)議笼吟,實(shí)施起來相對容易。目前為止抛姑,已經(jīng)投入使用的方案較多是采用中間服務(wù)器(大的比特交易區(qū)則為中間服務(wù)器)赞厕,需要CoinJoin用戶在服務(wù)器上進(jìn)行登記,由服務(wù)器聚合多個用戶請求生成大的交易定硝,經(jīng)過各個用戶進(jìn)行簽名后發(fā)布到比特幣網(wǎng)絡(luò)中來。然而事情并不是十全十美的毫目,雖然我們使用這種方法可以達(dá)到混淆的目的蔬啡,但是中間服務(wù)器可以掌握所有用戶的輸入輸出地址诲侮,對于該服務(wù)器來說用戶的隱私則一覽無余。倘若中間服務(wù)器被攻破箱蟆,那么我們所有的信息則就都被公開了沟绪。
(這就如同密碼協(xié)議中所討論的是否選擇有CA的方案那樣,CA作為一個中間管理者可以方便我們協(xié)議的執(zhí)行空猜,但是CA又會成為我們系統(tǒng)協(xié)議的漏洞點(diǎn)所在)
談及CoinJoin的思想绽慈,我們就應(yīng)該談?wù)撓滤涞氐木唧w協(xié)議算法——Coin Shuffle。
混幣(Coin Shuffle)是一個去中心化的隱私功能辈毯,它可以讓用戶快速高效地與其他用戶的資金進(jìn)行混合坝疼,在現(xiàn)有的用戶賬戶和混幣后的新賬戶之間創(chuàng)建隨機(jī)的映射關(guān)系,從而實(shí)現(xiàn)完全匿名谆沃。
在這里我只點(diǎn)一下混幣的概念钝凶,具體的算法內(nèi)容我在以后的稿子中進(jìn)行詳細(xì)的說明。大家可參考混幣原論文唁影。
四耕陷、Zcash中的匿名性
Zcash是一個去中心化的開源密碼學(xué)貨幣項目,通過使用先進(jìn)的密碼學(xué)技術(shù)提供交易隱私和可選擇的透明性据沈。Zcash支付被發(fā)布在一個公有區(qū)塊鏈上哟沫,但是交易發(fā)送者、接收者和交易數(shù)額是保密的锌介。
我們?yōu)槭裁匆獑为?dú)將Zcash拿出來談?wù)撃啬嫌茫窟@里就要說一下Zcash的特點(diǎn)。從上述文章中我們知道掏湾,比特幣的匿名性其實(shí)并不是很好裹虫。所以Zcash利用了密碼學(xué)中的“零知識證明”來增強(qiáng)交易的匿名性。
Zcash使用一個被稱為 zk-SNARK的零知識證明架構(gòu)融击,該架構(gòu)是由我們的經(jīng)驗豐富的密碼學(xué)家團(tuán)隊在近期的突破基礎(chǔ)上開發(fā)的凑兰。這個框架允許網(wǎng)絡(luò)在不公開交易參與方或者交易數(shù)額的情況下維護(hù)一個安全的賬戶余額賬本。Zcash交易的元數(shù)據(jù)是加密的陕贮,而不是公開地展示交易參與方和交易數(shù)額城看,zk-SNARK被用來證明沒有人進(jìn)行欺騙或者偷竊。
除此之外拇涤,Zcash除了對隱私有極大追求的匿名功能外捣作,也可以進(jìn)行公開透明的交易,其操作類似于比特幣鹅士,而與比特幣最大的不同是Zcash給客戶同時提供了透明地址和隱私地址以供選擇券躁,當(dāng)你需要隱藏賬戶的資金時,則可以選擇向隱私地址發(fā)送Zcash,如果你不需要將交易的資金隱藏起來也拜,你也可以選擇使用向透明地址發(fā)送Zcash的方式完成交易以舒。
下面我們就詳細(xì)的說明一下Zcash中所涉及的密碼學(xué)知識以及協(xié)議內(nèi)容。
零知識證明
“零知識證明”在我看來是密碼學(xué)中非常有意義的一個發(fā)現(xiàn)慢哈。簡單來說蔓钟,零知識證明是證明者能夠在不泄露任何有用信息的情況下,使驗證者相信他知道的一個秘密卵贱。例如:A在PKU上學(xué)滥沫,而他想向B證明他事實(shí)如此,但是卻又不想給B看他的錄取通知書(比如通知書的照片太丑等原因emmmm)键俱,此時A用零知識證明就可以達(dá)到這個目的兰绣。
而零知識證明有一下三個條件:
完備性:如果證明方和驗證方都是誠實(shí)的,并遵循證明過程的每一步方妖,進(jìn)行正確的計算狭魂,那么這個證明一定是成功的,驗證方一定能夠接受證明方党觅。
可靠性:沒有人能夠假冒證明方雌澄,使這個證明成功。
零知識性:證明過程執(zhí)行完之后杯瞻,驗證方只獲得了“證明方擁有這個知識”這條信息镐牺,而沒有獲得關(guān)于這個知識本身的任何一點(diǎn)信息。
Zcash的零知識證明理論
上面我們介紹了零知識證明的具體內(nèi)容魁莉,下面我們根據(jù)Zcash中的具體協(xié)議來分析睬涧。
在比特幣的協(xié)議中,當(dāng)A準(zhǔn)備向B進(jìn)行交易一張“支票”旗唁。那么B將生成一份新的同等金額的“支票”畦浓,而A中的支票進(jìn)行銷毀處理。而這個過程會被礦工進(jìn)行記賬處理检疫,并發(fā)布給所有節(jié)點(diǎn)讶请。
而Zcash為了增強(qiáng)匿名性,它擁有兩種地址:z-地址與t-地址屎媳。其中t地址是公開地址(如同比特幣中地址)而z地址是秘密地址夺溢。此時如果A要轉(zhuǎn)賬支票給B,要經(jīng)過如下的過程:
-
1 烛谊,A用自己的私鑰對支票進(jìn)行簽名风响,并得到一串新的字符串r。此時我們用Z1代表A的支票丹禀。
image.png -
2 状勤,而與比特幣一樣鞋怀,B也需要新建一張支票(Z2),而Z2與Z1的代號并不相同荧降。
image.png 3接箫,當(dāng)交易產(chǎn)生時攒读,我們需要銷毀原A的支票朵诫。但是與比特幣不同的是,我們不是直接銷毀Z1薄扁,而是引入了“作廢文件列表”的概念剪返。從下圖可以看出,原先的A持有的支票仍舊存在邓梅,并沒有消失脱盲,只是這張支票已經(jīng)被記入“作廢列表”。在確定資產(chǎn)所有權(quán)時要同時讀取兩個列表的信息日缨,能確定Bob擁有資產(chǎn)所有權(quán)的判斷方法是:作廢列表中不存在B所持“支票”的代號钱反。
簡單來說,發(fā)票列表里的值是不會被刪除的匣距。當(dāng)發(fā)票不能使用后直接記錄在作廢列表里即可面哥。
而在具體的交易過程中,我們可以進(jìn)行如下操作:
首先我們定義每個用戶的私鑰為PK1毅待、PK2....PKn尚卫。
之后我們定義n個支票Note1=(PK1 , r1)、Note2=(PK2 , r2)........Noten=(PKn , rn)
為了達(dá)到匿名的效果尸红,我們使用哈希函數(shù)對其壓縮吱涉,使其不可逆。H1=HASH(Note1)外里、 H2=HASH(Note2).......Hn=HASH(Noten)
之后引入廢棄集合的概念:
發(fā)票列表 | 廢棄列表 |
---|---|
H1=HASH(Note1) | HASH(Z1) |
H2=HASH(Note2) | |
H3=HASH(Note3) |
上面的列表中代表我共產(chǎn)生了n個支票怎爵,Z1為支票標(biāo)識,廢棄列表中的Z1表示我第一張發(fā)票是作廢無用的
當(dāng)用戶2要給用戶4轉(zhuǎn)移一張支票時盅蝗,用戶2會選擇隨機(jī)數(shù)r4并生成新的支票
Note4 = (PK4 , r4)
并將其密碼傳遞給用戶4鳖链。之后用戶2將HASH(Z2)
與HASH(Note4)
發(fā)送給系統(tǒng)中所有的節(jié)點(diǎn)。并得到如下表格:
發(fā)票列表 | 廢棄列表 |
---|---|
H1=HASH(Note1) | HASH(Z1) |
H2=HASH(Note2) | HASH(Z2) |
H3=HASH(Note3) | |
H4=HASH(Note4) |
這些過程均由礦工進(jìn)行記賬风科。因為資產(chǎn)只能有一份撒轮,所有礦工手里還有一個作廢列表。Alice要同時廣播自己的“發(fā)票代號”贼穆,錄入作廢列表中题山。發(fā)票代號也是加密的。所以礦工們能看到的信息其實(shí)是這樣的故痊。其中Alice的支票是原先存在的顶瞳,Alice的支票代號r1和Bob的支票是在交易過程中被Alice廣播的。
礦工們能獲取的信息相當(dāng)有限,但是這并不影響對礦工對交易有效性的判斷慨菱。
判斷的邏輯相當(dāng)簡單:礦工拿到A給的支票代號Z1焰络,去作廢列表中檢索,假如作廢列表中已經(jīng)存在Z1符喝,則證明Z1所對應(yīng)的的支票早已失效闪彼;若作廢列表中并不存在Z1,則證明Z1對應(yīng)的支票仍舊有效协饲,此時礦工把Z1錄入作廢列表中畏腕,把新生成的支票錄入支票列表中。所以記賬的過程就是對原有支票登記失效茉稠,并存入現(xiàn)有支票票的過程描馅。
在這個過程中,我們不難發(fā)現(xiàn)而线,每筆交易礦工能接收到的東西只有一個發(fā)票代號铭污,和一張新的發(fā)票,而且這兩樣?xùn)|西都是被加密的膀篮。所以礦工并不知道轉(zhuǎn)賬雙方是誰嘹狞,也不知道轉(zhuǎn)賬金額是多少。
Zcash零知識證明具體算法
由于算法篇幅過長各拷,我后續(xù)文章會將算法的具體數(shù)學(xué)公式推導(dǎo)列出刁绒。這里放上參考文檔。SNARKs英文文檔
零知識證明與zkSNARK
五烤黍、最強(qiáng)門羅幣
根據(jù)我們上述內(nèi)容所看知市,匿名性不是那么容易就達(dá)到的。那有沒有真正可以做到匿名的數(shù)字貨幣呢速蕊?下面讓我們看一看門羅幣的介紹嫂丙。
門羅幣的匿名性主要是由其環(huán)形簽名技術(shù)實(shí)現(xiàn)的。在十七世紀(jì)的時候规哲,法國群臣向國王進(jìn)諫時跟啤,為了不讓國王追查到是由誰帶頭簽名上書的,于是他們發(fā)明出了一種環(huán)形簽名的方式唉锌,所有人的姓名按環(huán)形排列隅肥,自然的隱藏了簽名順序,從而做到無法追查源頭袄简。
對于匿名性來說腥放,我們要做到以下兩點(diǎn)才算合格:1,接收方不可追蹤绿语、2秃症,發(fā)送方不可追蹤
候址。而對于門羅幣來說,以下三點(diǎn)是滿足他匿名性的關(guān)鍵种柑。
- 環(huán)簽名 - 發(fā)送方岗仑,不可追蹤
- 混淆地址 - 接收方,不可鏈接
- 環(huán)機(jī)密 - 交易金額的隱匿
環(huán)簽名
大家聯(lián)名上書提意見的時候聚请,怎樣讓外界難以猜測發(fā)起人是誰荠雕?上書人的名字可以寫成一個環(huán)形,環(huán)中各個名字的地位看上去彼此相等良漱,因此難以猜測發(fā)起人是誰舞虱。假設(shè)欢际,Alice 發(fā)送 5XMR(XMR 即門羅幣) 給 Bob母市,設(shè)定混淆交易數(shù)量為5。網(wǎng)絡(luò)在轉(zhuǎn)賬時會自動生成5筆5XMR的轉(zhuǎn)賬交易损趋,除了Alice發(fā)送給Bob的這筆患久,另外的4筆都是用來瞞騙外界觀測者的“誘騙交易”,這樣達(dá)到隱匿發(fā)送方的目的浑槽。
地址混淆
混淆地址是為了打破輸入輸出地址之間的關(guān)聯(lián)蒋失,以此隱匿轉(zhuǎn)賬的來去關(guān)系。每當(dāng)發(fā)送者要發(fā)起一筆轉(zhuǎn)賬的時候桐玻,這筆資金不會直接打到接收方的地址篙挽,而是打到一個系統(tǒng)臨時生成的地址。
Alice向Bob轉(zhuǎn)賬時镊靴,發(fā)送者Alice用接受者Bob的公鑰私鑰加上一些隨機(jī)數(shù)铣卡,生成一個獨(dú)一無二的、一次性的地址偏竟,系統(tǒng)給這個臨時地址添加5XMR煮落。觀測者,包括Alice踊谋、Bob自己都能看到這個臨時地址蝉仇,但都不知道地址里的錢屬于誰。那么Bob怎么知道有人給自己轉(zhuǎn)賬殖蚕,怎么收到這筆錢呢轿衔?Bob的錢包會用私鑰進(jìn)行搜索功能,查看區(qū)塊鏈上的臨時地址是否有屬于自己的錢睦疫。當(dāng)Bob的私鑰(僅有接收方Bob自己的私鑰能夠)識別出自己有權(quán)認(rèn)領(lǐng)的臨時地址害驹,就能使用這筆錢。
環(huán)機(jī)密
Alice怎么告訴區(qū)塊鏈網(wǎng)絡(luò)轉(zhuǎn)賬金額是5XMR呢笼痛?在 RingCT 的交易中, Alice 不會直接公開給網(wǎng)絡(luò)5XMR裙秋,而是提供一個數(shù)字rct,作為交易金額輸出琅拌。rct= 隨機(jī)數(shù) + 5(真正的交易金額)。 隨機(jī)數(shù)是用來為真實(shí)金額遮蓋的摘刑,由錢包自動產(chǎn)生进宝。網(wǎng)絡(luò)可使用這個rct值去驗證交易輸入是否等于交易輸出的金額,以確認(rèn)沒有額外的 門羅幣被偽造產(chǎn)生枷恕。 然而党晋,對于一個外部的觀察者而言,無從得知實(shí)際交易金額徐块。
可以參考文章門羅幣基礎(chǔ)技術(shù)介紹
六未玻、總結(jié)
區(qū)塊鏈?zhǔn)乾F(xiàn)在時代的熱門話題,而對于我們信息安全的研究人員來說胡控,如何使用密碼學(xué)領(lǐng)域的知識來加強(qiáng)區(qū)塊鏈的安全是我們需要研究的扳剿。本次文章我從比特幣開始到門羅幣,一步一步由弱到強(qiáng)分析了區(qū)塊鏈不同應(yīng)用的匿名性昼激。文章中涉及到許多源碼庇绽、英文文檔的解讀所以部分長篇幅的內(nèi)容暫時沒辦法呈現(xiàn),后續(xù)我會持續(xù)進(jìn)行深度挖掘來為讀者們呈現(xiàn)更精彩的區(qū)塊鏈安全知識橙困。
七瞧掺、參考鏈接
文章是在筆者大量閱讀以及自身思考后進(jìn)行的總結(jié),文中也參考了部分文章的知識凡傅,特此感謝1俦贰!
- 1 https://blog.csdn.net/jeason29/article/details/51576659
- 2 https://en.wikipedia.org/wiki/CoinJoin
- 3 http://www.reibang.com/p/93b1ccf7f3e1
- 4 http://www.reibang.com/p/93b1ccf7f3e1
- 5 http://www.reibang.com/p/4cc80bd7f29e
有興趣的話大家可以給我評論夏跷,技術(shù)無界限哼转,歡迎多多討論!