小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Atlassian JIRA 授權(quán)許可證機(jī)制分析

 quasiceo 2018-04-13
大眼夾的鳥(niǎo)巢 2012-12-273387 閱讀

JIRA在Atlassian開(kāi)發(fā)的各種產(chǎn)品中算是最著名的一個(gè),它主要是用來(lái)做產(chǎn)品缺陷跟蹤和項(xiàng)目管理的。JIRA是商業(yè)軟件,它的授權(quán)是按使用用戶數(shù)劃分的,最便宜的10用戶版本只要10美元,這極大地方便了小型團(tuán)隊(duì)的開(kāi)發(fā),不過(guò)25個(gè)用戶的授權(quán)版本就高達(dá)1200美元了。今天來(lái)講一講JIRA的軟件許可證是如何授權(quán)的。事實(shí)上Atlassian的諸多產(chǎn)品例如協(xié)作和內(nèi)容共享應(yīng)用Confluence、版本控制解決方案Stash等都是采用的類(lèi)似的授權(quán)機(jī)制。

more

從一條Lincense談起

在Atlassian網(wǎng)站上,用戶可以申請(qǐng)JIRA的一個(gè)月試用許可證。授權(quán)信息的生成需要用戶提供一個(gè)Server ID,它是在安裝完JIRA第一次啟動(dòng)時(shí)由客戶端生成的。隨后便可以得到一個(gè)完整的許可證字符串:

AAABDg0ODAoPeNptUNtKxDAQfc9XBHyOpKlttZCH2gas9LK0VRF8idlRI91akrS4f293q4iyMAPDnMsc5uwBtjgDhVmI6VXsRbEf4rTtMKMeQxlYZfTo9MfAb/MmeYqxmGU/ycMGpQaOQyYd8AOfLMUi9
K6NPC+0gsGC2OqjWlSdaDZN3gr068CdmeAPvduPUMkd8LQuS9GkeVKsuFROz7AK+pV7D8YeTBgqp
R4cDHJQID5HbfY/iXxCPcJCVJtXOWi7Hk17PY7a4Q6sW82rafcMpn65s4slJx5qwcxg8oxf06AgNTzSZFEAWkuxCNqRcWXJgXzaHQZROg7+0Iv8uwUcjrUZjLqTVr4/74vnyt/nTAsAhR8v6Zm5YfvZWVBnwouY7xhT+jwUgIUbRhGVaC8P9JCvDPT1MXIwnCgGqA=X02dp

明眼人一看這顯然是經(jīng)過(guò)Base64編碼的,不過(guò)在補(bǔ)齊長(zhǎng)度的結(jié)尾=后面還有五個(gè)字符。其中第一個(gè)X是一個(gè)固定的分隔符;緊接著的02代表許可證版本,即第二版;最后的dp是長(zhǎng)度校驗(yàn)碼,它是由31進(jìn)制轉(zhuǎn)換而來(lái)。dp轉(zhuǎn)成十進(jìn)制就是428,可以看到去掉最后五個(gè)字符和所有換行符后,許可證真正的字符串長(zhǎng)度的確是428。

解碼Base64

以下的內(nèi)容用Python演示,首先將其解碼。

>>> license = 'AAABDg0ODAoPeNptUNtKxDAQfc9XBHyOpKlttZCH2gas9LK0VRF8idlRI91akrS4f
q4iyMAPDnMsc5uwBtjgDhVmI6VXsRbEf4rTtMKMeQxlYZfTo9MfAb/MmeYqxmGU/ycMGpQaOQyYd8
AOfLMUi9K6NPC+0gsGC2OqjWlSdaDZN3gr068CdmeAPvduPUMkd8LQuS9GkeVKsuFROz7AK+pV7D8YeT
BgqpR4cDHJQID5HbfY/iXxCPcJCVJtXOWi7Hk17PY7a4Q6sW82rafcMpn65s4slJx5qwcxg8oxf06AgN
TzSZFEAWkuxCNqRcWXJgXzaHQZROg7+0Iv8uwUcjrUZjLqTVr4/74vnyt/nTAsAhR8v6Zm5YfvZWVBn
wouY7xhT+jwUgIUbRhGVaC8P9JCvDPT1MXIwnCgGqA='>>> len(license)>>> import base64>>> s = base64.b64decode(license)>>> s'\x00\x00\x01\x0e\r\x0e\x0c\n\x0fx\xdamP\xdbJ\xc40\x10}\xcfW\x04|\x8e\xa4\xa9m\x
b5\x90\x87\xda\x06\xac\xf4\xb2\xb4U\x11|\x89\xd9Q#\xddZ\x92\xb4\xb8\x7fow\xab\x8
\xb20\x03\xc3\x9c\xcb\x1c\xe6\xec\x01\xb68\x03\x85Y\x88\xe9U\xecE\xb1\x1f\xe2\x
b4\xed0\xa3\x1eC\x19Xe\xf4\xe8\xf4\xc7\xc0o\xf3&y\x8a\xb1\x98e?\xc9\xc3\x06\xa5x06\x8eC&\x1d\xf0\x03\x9f,\xc5"\xf4\xae\x8d</\xb4\x82\xc1\x82\xd8\xea\xa3ZT\x9dh
M\xde\n\xf4\xeb\xc0\x9d\x99\xe0\x0f\xbd\xdb\x8fP\xc9\x1d\xf0\xb4.K\xd1\xa4yR\xa
c\xb8TN\xcf\xb0\n\xfa\x95{\x0f\xc6\x1eL\x18*\xa5\x1e\x1c\x0crP >Gm\xf6?\x89|B=\x
c2BT\x9bW9h\xbb\x1eM{=\x8e\xda\xe1\x0e\xac[\xcd\xabi\xf7\x0c\xa6~\xb9\xb3\x8b%\'
\x1ej\xc1\xcc`\xf2\x8c_\xd3\xa0 7\xb4\xf3I\x91D\x01i.\xc4#jE\xc5\x97&\x05\xf3htx19D\xe8;\xfbB/\xf2\xec\x14r:\xd4f2\xeaMZ\xf8\xff\xbe/\x9f+\x7f\x9d0,\x02\x14|\x
bf\xa6f\xe5\x87\xefeeA\x9f\n.c\xbcaO\xe8\xf0R\x02\x14m\x18FU\xa0\xbc?\xd2B\xbc3xd3\xd4\xc5\xc8\xc2p\xa0\x1a\xa0'

解碼出來(lái)的內(nèi)容,由三部分組成。第一部分是前四個(gè)字節(jié),代表著第二部分的長(zhǎng)度,因此根據(jù)第一部分的值便可以切割出后面兩個(gè)部分。

在上面的例子中,一個(gè)部分的值是\x00\x00\x01\x0e。JIRA的主要實(shí)現(xiàn)語(yǔ)言是Java,這里的四個(gè)字節(jié)是使用DataInput接口中的readInt()方法讀取的。若將四個(gè)字節(jié)代表的8位整數(shù)分別稱作a, b, c, d,則它表示的整數(shù)可以通過(guò)如下方法得出:

(((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff))

Java的內(nèi)部編碼基本遵循UTF-32BE,即將Unicode全部字符用四字節(jié)固定長(zhǎng)度編碼,并且字節(jié)序?yàn)锽ig Endian。在Python端,我們可以這樣解碼:

>>> ord(s[:4].decode('UTF-32BE'))

得到了這個(gè)長(zhǎng)度,便可以將上面的內(nèi)容分割成兩部分了,稱前一部分為licenseText,后一部分為licenseSig。

>>> licenseText, licenseSig = s[4:4 + 270], s[4 + 270:]>>> licenseText'\r\x0e\x0c\n\x0fx\xdamP\xdbJ\xc40\x10}\xcfW\x04|\x8e\xa4\xa9m\xb5\x90\x87\xda\x
\xac\xf4\xb2\xb4U\x11|\x89\xd9Q#\xddZ\x92\xb4\xb8\x7fow\xab\x88\xb20\x03\xc3\x
c\xcb\x1c\xe6\xec\x01\xb68\x03\x85Y\x88\xe9U\xecE\xb1\x1f\xe2\xb4\xed0\xa3\x1eC
\x19Xe\xf4\xe8\xf4\xc7\xc0o\xf3&y\x8a\xb1\x98e?\xc9\xc3\x06\xa5\x06\x8eC&\x1d\xf
\x03\x9f,\xc5"\xf4\xae\x8d</\xb4\x82\xc1\x82\xd8\xea\xa3ZT\x9dh6M\xde\n\xf4\xeb
\xc0\x9d\x99\xe0\x0f\xbd\xdb\x8fP\xc9\x1d\xf0\xb4.K\xd1\xa4yR\xac\xb8TN\xcf\xb0n\xfa\x95{\x0f\xc6\x1eL\x18*\xa5\x1e\x1c\x0crP >Gm\xf6?\x89|B=\xc2BT\x9bW9h\xbbx1eM{=\x8e\xda\xe1\x0e\xac[\xcd\xabi\xf7\x0c\xa6~\xb9\xb3\x8b%\'\x1ej\xc1\xcc`\x
f2\x8c_\xd3\xa0 7\xb4\xf3I\x91D\x01i.\xc4#jE\xc5\x97&\x05\xf3ht\x19D\xe8;\xfbB/xf2\xec\x14r:\xd4f2\xeaMZ\xf8\xff\xbe/\x9f+\x7f\x9d'>>> licenseSig'0,\x02\x14|\xbf\xa6f\xe5\x87\xefeeA\x9f\n.c\xbcaO\xe8\xf0R\x02\x14m\x18FU\xa0\x
bc?\xd2B\xbc3\xd3\xd4\xc5\xc8\xc2p\xa0\x1a\xa0'

zlib 解壓縮

licenseText的前五個(gè)字節(jié)是一個(gè)識(shí)別字串,由五個(gè)固定的ASCII碼組成。

>>> map(ord, '\r\x0e\x0c\n\x0f')[13, 14, 12, 10, 15]

去掉這個(gè)前綴后的內(nèi)容是經(jīng)過(guò)zlib壓縮的,我們將其解壓后便得到了原始的許可證內(nèi)容。

>>> import zlib>>> licenseTextOriginal = zlib.decompress(licenseText[5:])>>> print licenseTextOriginal#Wed Dec 26 09:17:36 CST 2012Description=JIRA\: EvaluationCreationDate=2012-12-27jira.LicenseEdition=ENTERPRISEEvaluation=truejira.LicenseTypeName=COMMERCIAL
jira.active=truelicenseVersion=2MaintenanceExpiryDate=2013-01-26Organisation=Clippit Testjira.NumberOfUsers=-1ServerID=ABCD-1234-EFGH-5678SEN=SEN-L2107857LicenseID=LIDSEN-L2107857LicenseExpiryDate=2013-01-26PurchaseDate=2012-12-27

上面的ServerID已被隱去??梢钥闯鲞@個(gè)許可證的內(nèi)容是非常明確的,在這里就不多解釋了。

DSA with SHA-1 數(shù)字簽名

可以看到上面的各種方法至多可以保證許可證內(nèi)容的正確性,卻沒(méi)有辦法保證鑒別性和不可否認(rèn)性。JIRA采用了數(shù)字簽名的方法來(lái)確保軟件許可證的安全,具體而言,便是DSA算法。

DSA(Digital Signature Algorithm)和更為普遍的RSA算法一樣都是基于公鑰私鑰的加密系統(tǒng)(DSA和RSA的比較可以參考這里)。

JIRA客戶端中存儲(chǔ)的公鑰在atlassian-extras-2.2.2.jar文件的com.atlassian.extras.decoder.v2.Version2LicenseDecoder類(lèi)中。為了使其能夠正確被Python的OpenSSL庫(kù)M2Crypto識(shí)別,需要把它提取出來(lái)并在首尾加上-----BEGIN PUBLIC KEY----------END PUBLIC KEY-----的標(biāo)記。接著來(lái)嘗試一下驗(yàn)證的過(guò)程:

>>> from M2Crypto import DSA>>> import hashlib>>> pk = DSA.load_pub_key('./official_pubkey.pem')>>> pk.verify_asn1(hashlib.sha1(licenseText).digest(), licenseSig)

偽造數(shù)字簽名

數(shù)字簽名的安全性還是極高的,通過(guò)公鑰推導(dǎo)出私鑰,以現(xiàn)有的計(jì)算能力是幾乎不可能的事。所以一般針對(duì)數(shù)字簽名的破解方法便是設(shè)法替換掉預(yù)設(shè)的公鑰,使用自己的密鑰對(duì)。創(chuàng)建密鑰對(duì)也是很簡(jiǎn)單的事:

>>> dsa = DSA.gen_params(1024)..+.....+.......+.+.........+............+.+........+.......+++++++++++++++++++++++++++++++++++++++++++++++++++*.......+.......+....+..+.............+...................+...+........+........+....+.......+......+..........+....+.+....+............+..+....+.......+...+.+..+.........+...+..+................+.........+..+.......+..................+....+....+.................+.............+...........+++++++++++++++++++++++++++++++++++++++++++++++++++*>>> dsa.gen_key()>>> dsa.save_key('./private.pem', cipher=None)>>> dsa.save_pub_key('./public.pem')

接下來(lái)的問(wèn)題便是如何修改編譯好的.class文件。Java反編譯器可以將它還原成.java文件,修改后再重新編譯成.class文件即可。不過(guò)這里只需要修改一個(gè)靜態(tài)的字符串,所以也無(wú)需大動(dòng)干戈,使用一個(gè)叫做dirtyJOE的軟件,便可以直接修改.class文件中的常量池。把偽造出來(lái)的公鑰內(nèi)容去掉首尾標(biāo)記和換行符,改寫(xiě)原來(lái)的公鑰,最后保存文件并替換掉atlassian-extras-2.2.2.jar里原先的那個(gè)。

許可證生成器

既然全部的過(guò)程都已經(jīng)還原,那么反推一下便可以生成自己的許可證了。

額外的修改

事實(shí)上,在JIRA中還有其他地方保存了這個(gè)公鑰,具體來(lái)說(shuō)是它的Universal Plugin Manager的相關(guān)代碼。如果僅僅修改了上面提到的文件,是沒(méi)有辦法使用JIRA的插件功能的。只有將所有有關(guān)的地方全部替換成自己偽造的公鑰,才能保證整個(gè)軟件全部可用。

2012 PHP 世界年度回顧 Seedbox配置實(shí)例

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多