我們致力於保護用戶的權利並對我們的原始碼採取透明立場。這讓感興趣的各方人員能獨立檢查原始碼的安全性、完整性和正確性。
原始碼
MEGA SDK
歡迎使用MEGA SDK!我們希望它對有興趣將MEGA支援整合到他們的應用程式中的開發人員有用。
MEGA SDK包含原始碼和文件,使您能夠以舒適的高抽象級別使用MEGA的API功能。它的核心組件-一個稱為客戶端存取引擎的程式碼模組-在記憶體中維護使用者帳戶當前的副本(包括所有相關檔案、資料夾、聯絡人和共享),接受來自應用程式的指令,並透過回調通知應用程式指令結果和其它更新。
MEGA客戶端存取引擎作為一組C++類別和介面。如果您使用C++,僅需將它們加到您的專案即可。然後將MegaClient類別(會保存工作階段狀態)實體化並將HttpIO介面(處理網路請求和blocking)和MegaApp(通過它接收引擎的回調)實做的實體傳遞給它。
核心程式碼與平台無關(如果您在特定的C++編譯器環境中遇到任何問題,請告訴我們)。 為了展示實際使用,會包含一個示範應用程式(一個基本的ftp設計的互動式控制台客戶端)。
與編譯原生碼的整合專案的要求排除所有依賴特定直譯器或執行環境的語言。作為幾乎所有現代系統的「通用語言」,C語言本是顯而易見的選擇,但C++的語法糖和模板函式庫提供的程式碼緊湊性和可讀性優勢非常值得少量的添加集成開銷。我們將與感興趣的開發人員合作,透過原始碼模塊/擴展(而不是將功能移植到目標語言本身)將MEGA支援加到他們的喜好的環境中。如果您願意並能夠為特定的集成工作做出貢獻,請透過developers@mega.nz與我們聯繫。
應用程式透過非阻塞調用MegaClient物件的方法向客戶端存取引擎提交請求,並透過調用其實作MegaApp介面的物件的方法向應用程式發送事件信號。
資料和資料夾由節點物件表示並由節點控制代碼引用。節點指向父節點,形成資料結構樹。資料結構樹只有一個根節點(不允許循環連接)。節點更新(由工作階段自身的操作、同一帳戶的其他工作階段或其他帳戶引起的,例如透過共享文件夾中的活動)透過指定受影響節點的回調即時通知。刪除的節點在被清除之前會先收到已刪除標記集的通知,以便應用程式有機會從介面中刪除它們。
每個帳戶至少有三個節點資料結構樹:Root、incoming和rubbish。其它額外資料結構樹可來自其他用戶的共享資料夾。
使用者由他們的使用者控制代碼和/或他們的主要電子郵件地址引用。引擎為當前工作階段上下文中出現的每個使用者帳戶維護一個使用者物件:聯絡人或僅是檔案系統節點的擁有者。如果設定了可見性標記,則會將使用者轉為聯絡人。
使用者屬性可用於儲存大頭貼圖片、地址、出生日期等憑證。建議儲存應用程式隱私使用者憑證AES-CBC加密。
所有引擎方法都是非阻塞的-等待網路通訊來完成不是一種選擇。相反的,他們只初始化所需的操作,最終結果透過回調傳送信號。應用程式應該能夠抵抗這類經過一段時間後(例如很多秒之後)到達的回調。失敗的請求(例如由於網路問題)會使用指數輪詢算法自動重試。應用程式𨘋過回調接收通知,並應該相應地通知使用者,以及用於手動初始化重試的介面元素。
此三種類型的操作受稱為「推測即時完成」的機制加速:節點屬性更新、移動和刪除。由於這些僅從API收到高度可預測的「OK」或「失敗」回應,因此在罕見的不一致事件中立即更新本地節點並重新加載工作階段狀態有一些好處。引擎透過存取檢查鬆散地保護它們,該存取檢查遵循與API伺服器端的授權檢查相同的語意。
基於潛在過時(由於網路延遲)視圖對資源(使用者帳戶可存取的可寫入節點)的共享存取自然容易出現競爭狀況,當兩方在延遲視窗內進行衝突更新時會導致不一致。該引擎包含檢測這些衝突的啟發式方法,並會在需要時要求應用程式丟棄並重新加載其視圖(應相應地通知使用者)。
由於其非阻塞性質,MEGA客戶端存取引擎與單線程應用程式整合得非常好(儘管在沒有非阻塞DNS查找工具的平台上,您可能無法繞過使用工作線程進行名稱解析)。但是,如果您喜歡使用多線程,歡迎您這樣做-只要您確保沒有兩個線程同時進入引擎或存取其資料結構。
有三種方法將引擎與應用程式整合。目的是讓引擎在其當中一個觸發器發動時迅速獲取CPU(透過MegaClient的exec()方法):
應用程式必須準備好處理檔案和資料夾名稱衝突。在許多情況下,這是不重要的-大部分基於它的時間戳,使用者看到所有副本並決定他感興趣的檔案。然而,有些應用程式將MEGA節點資料結構樹映射到使用檔案路徑作為唯一鍵的資源,例如檔案系統。在這種情況下,我們建議只使用最近的節點。
主機上不允許的檔案名稱字元必須使用%xx進行urlencoded。將檔案寫回伺服器時,有效的 urlencoded序列必須替換為編碼字元。這具有改編原先包含有效%xx序列檔案名稱的潛在不良副作用,但應該很少見,並且當讀回本地機器時改編將被取消。
我們懇請所有希望引入新節點、檔案或使用者屬性的應用程式開發人員與我們協調編號/命名和格式協定,以最大限度地提高跨應用程式的互操作性。如果您選擇不這樣做,請避免混亂命名空間,並在新屬性名稱前加上您公司或應用程式名稱的縮寫。
以下介面需要應用程式實作:
檔案存取
-檔案開啟/關閉/讀取/寫入HttpIO
-支援SSL的HTTP請求PrnGen
-強度高加密的偽隨機數產生器SymmCipher
-AES加密標準AsymmCipher
-RSA加密演算法MegaApp
-應用程式回調SDK提供FileAccess
(使用POSIX調用)、HttpIO
(使用cURL)和PrnGen SymmCipher
和AsymmCipher
(使用Crypto++)的參考實作。如果您決定在您的應用程式中使用cURL,請確保它是使用c-ares支援非同步DNS請求構建的。某些平台(例如MacOS和 Fedora)捆綁使用支援線程解析器編譯的cURL二進位文件-這些將無法工作。
要存取MEGA,應用程式需要實體化三個類別:
MegaApp
介面實作HttpIO
介面實作MegaClient
然後,應用程式必須緊接阻塞前或非阻塞時為事件本身調用MegaClient
的wait()
。 如果wait()
希望阻塞,它會調用HttpIO
的waitio()
,提供一個timeout。應用程式可以將自己的喚醒條件搭載到waitio()
中的socket事件/timeout上,或者記錄waitio()
被喚醒條件並將這些條件包含在自己的阻塞邏輯中。提供的SDK範例(megaapp.cpp)使用前一種方法,將fileno(stdin)
加到select()
fd集以即時處理使用者的輸入。
每次根據waitio()
準則喚醒後,應用程式必須至少調用MegaClient的exec()
一次(頻繁調用它不會有什麼問題)。
MEGA工作階段包括:
MegaClient::nodes
)1MegaClient::users
)1MegaClient::ft
)MegaClient::rootnodes
)MegaClient::me,MegaClient::myemail
)節點具有以下屬性:
有關詳細訊息,請參閱提供的原始碼。
因為工作階段中的使用者有聯繫關係,或者因為擁有至少一個工作階段節點,第三方使用者會是工作階段的一部分。當共享被加到一個先前未註冊的電子郵件地址時,也會建立使用者記錄。用戶可以透過他們的控制代碼或電子郵件地址被引用。
使用者屬性:
支援多並行檔案傳輸。強烈建議不要同時運行超過一個大型上傳和一個大型下載以避免網絡擁塞(即使有網路優勢也會因此變少)。檔案傳輸可以聚合多個TCP通道(推薦起始數量:4個)以獲得更大的總處理量。檔案傳輸可透過調用MegaClient::tclose()
隨時中止。ADSL上行網路中,上傳期間會很常見到嚴重的本地網路擁塞,這可以透過啟用自動或固定速率限制來防止。
傳輸批次檔案的應用程式應該使用引擎的傳輸佇列功能。它使用管線化(在當前傳輸結束前的約三秒時會處理新的傳輸)來減少或消除檔案之間的停滯時間。失敗的傳輸使用指數輪詢算法重試。
檔案可以有屬性。只有檔案的原始建立者才能更新它的屬性。所有引用相同加密檔案的節點都會看到相同的屬性。屬性帶有一個16位元的類型類位。客戶端存取引擎支援在上傳期間或上傳之後附加檔案屬性及其批量檢索。
所有能夠上傳圖像檔案的應用程式都應該在此過程中加入縮圖(請記住,我們無法在服務器端執行此操作)。縮圖以類型0的檔案屬性來儲存,而且應該壓縮到120p*120p 約3-4 KB大小的JPEG。隨SDK提供的應用程式範例演示瞭如何使用FreeImage儲存庫執行此操作。由於從大圖片產生縮圖可能會花費大量時間,因此亦建議在單獨的工作線程中執行此操作以避免應用程式停滯。
應用程式在運行期間可能會遇到兩種類型的配額限制:儲存配額和流量配額。根據政策,MEGA在這兩個部分都非常大方,這意味著您的使用群中只有一小部分用戶會用完配額,但如果發生這種情況,必須正確處理這種情況-需要通知使用者關於他上傳或下載失敗的原因,而不是讓服務看起來像故障而讓使用者不知所措。
如果沒有足夠的可用儲存配額來完成上傳,上傳將被拒絕並顯示錯誤EOVERQUOTA
。一旦上傳開始,它就會完成,即使您在此期間透過其它方式用完磁碟空間(例如,您的Pro狀態已過期)。當您的應用程式試圖將檔案發送到沒有足夠配額的第三方帳戶時,也會發生此錯誤。
如果過去五到六個小時內消耗的頻寬流量加上所有正在運行中的下載還需要用到的流量,加上即將進行下載的檔案大小超過當前每個IP的頻寬限制(如果有),則下載嘗試將被拒絕並顯示錯誤EOVERQUOTA
。
與上傳相反,正在運行的下載可能在某些情況下會因超出配額錯誤而中斷,這將觸發quota_exceeded()
回調,直到有可用的頻寬配額時,下載將自動重試。
您可以在我們的通用GitHub頁面上找到我們的其它函式庫。如果您想以超出這些許可範圍的方式將我們的原始碼用於商業用途,請聯繫我們進行討論。
C++ SDK的發布只是一個起點,它會隨著時間的推移而發展。我們希望聽到開發人員在他們的應用程式中實際使用它的意見-如果您發現錯誤、設計缺陷或其他缺點,請透過developers@mega.nz與我們聯繫。MEGA正在招聘,所以,若您的反饋表現您是一個聰明的人,請準備好接受我們的獎勵。
很快將會有開發人員論壇和原始碼儲存庫可用。
大型MEGA帳戶可能需要相當長的時間來加載。這是由於必須從API叢集讀取帳戶狀態資訊的絕對大小。針對此有兩種解決方法:
目前,檔案建立後無法修改。這個限制將透過使用加密的增量檔案來克服。
目前,檔案的完整性只有在它完整下載後才能得到驗證。區塊MAC驗證將使應用程式能夠確保部分讀取的完整性。
megaclient
要成功建構megaclient
,您需要具備以下條件:
目前,SDK沒有附帶autoconf指令,因此您可能需要手動調整Makefile以適應您的系統。
megaclient
類似於UNIXftp
指令,megaclient
顯示命令提示字元並接受指令登入MEGA帳戶或輸出資料夾連結、列出資料夾內容、建立資料夾、複製、移動和刪除檔案和資料夾、檢視內送和外送的資料夾共享、建立、修改和刪除外送的資料夾共享、上傳和下載檔案、匯出資料夾和檔案的連結、匯入檔案連結、檢視帳戶狀態和更改其密碼。
登入
-登入帳戶或資料夾連結要登入帳戶,請指定帳戶的電子郵件地址和可選的密碼(系統會提示您輸入密碼)。
要登入匯出的資料夾連結,請指定完整連結,包括金鑰(未輸入金鑰時會出現提示輸入)。
請注意,無法寫入匯出的資料夾。
mount1
-顯示可用的檔案系統資料結構樹此指令不帶任何參數並顯示可用檔案系統資料結構樹的路徑(通常/用於主結構,//in
用於收件夾,//bin
用於垃圾筒,email:sharename
用於來自使用者email
內送的共享。
ls
-列出檔案和資料夾ls
列出當前資料夾的內容(如果給用限定符-R,它會遞迴的做)或指定的路徑。
路徑可以是相對的或絕對的。有效的絕對路徑以mount指令顯示的其中一個前綴做為開頭。
檔案和資料夾屬性與其名稱一起顯示:檔案大小和可用的檔案屬性,或匯出的資料夾連結和外送的資料夾共享。
cd
-更改當前工作目錄cd
將當前工作目錄更改為指定的資料夾路徑。如果沒有給出路徑,它將更改為/。
pwd
-顯示當前資料夾pwd
將當前資料夾顯示為絕對路徑。
lcd
-更改當前本地工作目錄lcd
將當前本地工作目錄更改為指定路徑。
get
-將檔案加到下載佇列get
取得特定下載檔案的佇列。如果您指定一個資料夾,該資料夾裡的所有檔案都會被佇列下載(但不包括其子資料夾的內容)。
put
-將檔案加到上傳佇列put
放置特定上傳檔案的佇列。支援模式-put *.jpg
將上傳所有當前本地目錄中的*.jpg檔案。
getq
和putq
-列出/刪除/中止佇列中的傳輸佇列中的傳輸與索引、目標路徑(僅上傳的)和活動狀態一起列出。要取消傳輸,請指定其索引。
mkdir
-建立資料夾mkdir
在指定(或當前)資料夾中建立一個空的子資料夾。儘管MEGA允許相同的資料夾名稱,但如果資料夾已存在,則mkdir
會失敗。
cp
,mv
-複製或移除,重新命名檔案和資料夾指定的來源路徑或資料夾被複製或移動到目的地資料夾。如果目的地在現有資料夾裡會是一個新名稱,則在過程中會進行重新命名。
rm
-刪除檔案或資料夾rm
刪除指定的檔案或資料夾。如果資料夾包含檔案或子資料夾,這些也會被遞迴刪除。所有受影響的外送共享和匯出的資料夾連結都將在此過程中取消。
最後會刪除。若要利用垃圾筒功能,請改用mv path //bin
。
share
-管理外送的資料共享share
列出、建立、更新或刪除指定資料夾中外送的共享。該資料夾不能在內送的共享裡。
若要列出資料夾中現有的共享,請使用share path
。
若要取消對使用者的資料夾共享,請使用share path email
。
若要建立或修改資料夾共享,請使用share path email access
支援的存取級別是:唯讀(r
),讀取/寫入(rw
)和完整權限(full
)。
export
-建立或取消檔案或資料夾連結export1
建立包含相關加密金鑰的唯譯檔案或資料夾連結。若要取消現有連結,請加入關鍵字del
。
import
-匯入匯出的檔案import
將提供的連結(目前不支援匯入資料夾連結)所描述的檔案加到當前資料夾。
putbps
-設定上傳速度限制通過DSL線路上傳可能會導致顯著的外送數據封包遺失。您可以透過指定每秒位元組的絕對最大值來限制傳送的速率,自動
讓伺服器計算出您線路的速率並保留大約10%的線路空閒,或者不保留
以全速傳輸。
目前無法更改運行中上傳的傳送速率。此設定只會影響後續上傳。
whoami
-顯示帳戶詳細資料whoami
顯示各種帳戶配額、餘額和工作階段記錄。
passwd
-更改帳戶密碼passwd
提示輸入當前密碼,然後要求輸入新密碼並進行確認。不需執行密碼品質檢查。
retry
-立即重試所有待處理的操作retry
重置所有指數輪詢計時器。
recon
-重新連線recon
清除所有現有伺服器的連線。除了由於部分傳輸的區塊被捨棄並且必須重新傳送而導致傳輸花費更長的時間外,這對正在進行的操作沒有影響。
reload
-抹除並重新加載帳戶狀態reload
清除本地狀態並強制從伺服器重新加載。這在回應客戶端檢視和伺服器狀態之間與競爭情況相關的不一致檢測時很有用。
logout
-終止當前工作階段logout
清除所有本地工作階段狀態。
debug
-切換除錯模式除錯模式輸出HTTP連線活動和原始JSON API請求和回應。
雜湊UTF-8編碼的密碼並將結果儲存在提供的緩衝區中。
方法:error hashpw_key(const char* password, char* hash)
返回代碼:如果UTF-8編碼無效,則為API_EARGS
根據使用者電子郵件地址(不區分大小寫)和對應的密碼雜湊初始化工作階段登入。
方法:void login(const char* email, const char* hash)
回調:login_result(error e)
錯誤代碼:API_ENOENT
:無效的電子郵件地址或密碼,API_EKEY
:無法解密的私密金鑰
方法:void folderaccess(const char* node, const char* key)
回調:無(沒有與伺服器互動,繼續調用fetchnodes()
)
方法:void fetchnodes()
回調:fetchnodes_result(client, error e)
成功完成後,還會調用nodes_updated()。
方法:void getaccountdetails(AccountDetails* result, int storage, int transfer, int pro, int transactions, int purchases, int sessions)
使用當前儲存和傳輸利用情況和配額、Pro狀態以及交易和工作階段歷史記錄上的資訊更新所提供的AccountDetails結構。您可以透過將相關標記設定為非零值來指定您感興趣的資訊類型。
方法:error changepw(const char* currentpwhash, const char* newpwhash)
回調changepw_result(error e)
返回代碼:如果使用者工作階段不存在,則為API_EACCESS
。
方法error setattr(Node* node, const char** newattr)
回傳值:如果節點無法寫入,則為API_EACCESS
。
回調:setattr_result(handle nodehandle, error e)
節點的當前屬性被推送到伺服器。可選的newattr
參數將增量屬性指定為以NULL結尾的屬性名稱/屬性C字串指標對序列。在setattr_result()
中,nodehandle
是節點的控制代碼。
方法:error rename(Node* node, Node* newparent)
回傳值:API_EACCESS
如果節點的父節點或新的父節點不可寫入(分別具有完整權限和讀取/寫入存取權限)或者移動將在不同的使用者帳戶之間進行,API_ECIRCULAR
如果會導致循環連結。
回調:rename_result(handle nodehandle, error e)
節點(及其所有子節點)被移動到新的父節點,該節點必須與節點本身屬於同一使用者帳戶。您不能將節點移到它自己的子資料結構樹。
方法: error unlink(Node* node)
回傳值:API_EACCESS
如果節點的父節點不可寫入(具有完全存取權限)。
回調:unlink_result(handle nodehandle, error e)
節點及其所有子節點都將被刪除。節點的父節點必須是可寫入的(具有完全存取權限)。受影響的外送的共享會被取消。
上傳和下載是從topen()
開始的,它返回一個標記傳輸的傳輸描述符。多個傳輸可以並行運行,每個傳輸可以並行使用多個TCP連線。可以使用管線化進行高效率的傳輸佇列。可以使用絕對或動態上限來限制上傳速度。
進度資訊透過回調transfer_update(int td, m_off_t bytes, m_off_t size, dstime starttime)
傳達,其中td標記傳輸,bytes表示到目前為止傳輸的位元組,size表示總傳輸大小,starttime表示傳輸開始的時間。
可以透過調用tclose(int td)
隨時中止正在運行的傳輸。失敗指示回調暗中地執行tclose()
。如果應用程式回傳非零值,則會表示一個瞬態HTTP錯誤的回調,transfer_error(int td, int httpcode, int count)
將調用tclose()
。
方法int topen(const char* localfilename, int speedlimit, int connections)
speedlimit
-以位元組/秒為單位的最大上傳速度或-1表示大約90%的線路速度。
connections
-要使用的並行連線數(預設值:3)
返回值:如果所有傳輸通道都忙線中,傳輸描述符或API_ETOOMANY
,如果檔案開啟失敗,則為API_ENOENT
。
成功完成時回調:transfer_complete(int td, handle uploadhandle, const byte* uploadtoken, const byte* filekey, SymmCipher* filekey)
回調失敗:transfer_failed(int td, error e)
方法:int topen(handle nodehandle, const byte* key, m_off_t start, m_off_t len, int c)
nodehandle
是要下載的節點的控制代碼(如果有設定key,則為匯出檔案連結的控制代碼部分)
key
如果有設定,是匯出檔案連結的base64解碼金鑰部分
start
和len可以設定只下載檔案的一部分(預設值:0,-1則表示完整檔案)
c
表示此下載應使用的並行TCP連線數。
返回值:如果所有傳輸通道都忙線,傳輸描述符或API_ETOOMANY
,如果本地檔案不存在,則為API_ENOENT
,如果嘗試下載不是檔案,則為API_EACCESS3
要下載的檔案成功開啟時回調:topen_result(int td, string* filename, const char* fa, int pfa)
td
識別傳輸
filename
是節點屬性n指定的檔案名稱
fa
是可以用於此檔案的檔案屬性
pfa
是一個標記,表示提出請求的使用者是否允許寫入檔案屬性(例,是檔案的擁有者)
成功完成時回調:transfer_complete(int td, chunkmac_map* macs, const char* fn)
td
識別傳輸
macs
包含每個檔案區塊的MAC雜湊
fn
是檔案名稱(UTF-8)
失敗時回調:transfer_failed(int td, string& filename, error e)
達到傳輸限制時回調:transfer_limit(int td)
該引擎維持上傳和下載佇列獨立,為putq
和getq
。傳輸是透過將傳輸物件(FilePut
和FileGet
類別推進到這些佇列上)開始的。您不再需要自己調用topen()
/tclose()
,但您仍然需要處理傳輸回調。如果在至少XFERTIMEOUT分秒沒有傳輸任何位元組,傳輸將被視為失敗,在這種情況下,它將中止並以指數輪詢無限次數地重複進行。
使用引擎提供的傳輸佇列的主要好處不是降低應用程式的複雜性,而是內置的重疊傳輸管線可以減少檔案之間轉換對總體處理能力的影響。
可以增加節點到putnodes_result(error e, targettype t, NewNode* nn)
方法:void putnodes(handle parenthandle, NewNode* newnodes, int numnodes)
parenthandle
是新節點的父節點的控制代碼。
newnodes
是一組填充的NewNode結構的陣列。在某些情況下,在對putnodes()
的調用已經返回後,此陣列將可被存取。因此,總是從堆放空間中分配這個陣列並在putnodes_result()
中釋放它。
numnodes
是存在的NewNode記錄數。
回調:putnodes_result(client,error)如果操作
方法:setshare(node,targetuser,accesslevel)
回調:share_result(client,error)
回調:share_result(client,int,error)
方法:loggedin()
返回值:如果登入則為1,否則為0
方法:checkaccess(node,level)
返回值:如果允許存取則為1,否則為0
方法:checkmove(node,targetnode)
返回值:錯誤代碼(API_OK、API_EACCESS或API_ECIRCULAR)
方法:makeattr(cipher,targetstring,jsonstring,length)
回調:newfile()
返回值:特定應用程式的FileAccess物件
回調:users_updated(client,users,count)—加入或更新了使用者(使用者永遠不會被刪除)
回調:node_updated(client,nodes,count)-增加、更新或刪除節點
回調:notify_retry(client,time)-指定下一次重試之前的分秒時間
回調:reload(client,reason)-可能不一致,重新加載帳戶狀態
成功開發MEGA客戶端應用程式不需要了解以下低階細節。它提供給那些有興趣全面了解 MEGA API工作原理的人作為參考。
MEGA API基於簡單的HTTP/JSON請求-回應設計。請求以指令物件陣列的形式提交,可以由客戶端和伺服器端發起,有效地實現雙向RPC功能。要查看SDK的megaclient範例應用程式中的原始請求流程,請使用除錯指令。
所有對稱加密操作均基於AES-128。它以檔案和資料夾屬性區塊的密碼區塊連結模式和實際檔案資料的計數器模式運行。每個檔案和資料夾節點都使用自己隨機生成的128位元金鑰。檔案節點對屬性區塊和檔案資料使用相同的金鑰,加上一個64位元隨機計數器起始值和一個64位元meta MAC位址來驗證檔案的完整性。
每個使用者帳戶都使用一個對稱的主金鑰來為它自己的資料構樹中保存的節點的所有金鑰進行ECB加密。此主金鑰儲存在MEGA伺服器上,並使用從使用者的登入密碼取得的雜湊進行加密。
使用區塊CBC-MAC驗證檔案完整性。區塊大小從128 KB開始,增加到1 MB,這是儲存區塊MAC所需的空間與完整性檢查部分讀取的平均讀取時間之間的合理平衡。
除了對稱金鑰之外,每個使用者帳戶還有一個2048位元的RSA金鑰對,以安全地接收共享金鑰或檔案/資料夾金鑰等資料。它的私人組件透過使用者的對稱主金鑰進行加密儲存。
資料夾的擁有者全權負責管理存取;共享是不可傳遞的(無法在傳入共享的資料夾上建立共享)。共享資料夾中的所有參與者都透過共享一個特定共享的金鑰獲得加密存取權限,該金鑰是由擁有者透過RSA傳遞給新的參與者(理論上是從參與共享的任一人傳遞給新參與者,但如果核心架構遭到破壞,這將產生重大的安全風險)。共享資料夾中節點的所有金鑰,包括根節點,都被加密到此共享金鑰。將新節點加到共享資料夾的一方負責提供適切的節點/特定的共享金鑰。缺少的節點/特定的共享金鑰只能由共享擁有者提供。
MEGA支援安全的未經身份驗證的資料傳輸。任何完整註冊的使用者都可以透過他們的RSA公鑰在他們的收件夾中接收檔案或資料夾。
每次登入都會啟動一個新工作階段。對於一般帳戶而言,這涉及伺服器生成一個隨機工作階段標記並將其加密為使用者的私鑰。如果使用者密碼成功解密此私鑰,則認為使用者密碼已通過驗證,私鑰接著會解密工作階段標記。
為防止對使用者密碼進行遠端離線字典攻擊,只有當從密碼衍生出的雜湊值呈交給伺服器時,加密的私鑰才會提供給客戶端。
API請求有兩個方向:客戶端→伺服器和伺服器→客戶端
客戶端-伺服器請求以帶有原始JSON負載的HTTP POST形式發出。請求由一個或多個指令組成,並以單原子的、隔離的和一致的事務執行-在請求層級錯誤回應的事件下,沒有資料會被更改。請求是冪等的-多次發送相同的請求等同於發送一次,這使得重試它們變得安全,例如,如果出現間歇性網路問題。因此,每個請求都必須使用工作階段唯一的標識符(例如序列號)進行標記,以防止由前面的相同請求引起的無意緩存命中。
執行請求時,所有可能受其影響的使用者都將被鎖定。這包括發出請求的用戶以及處於共享資料夾關係和/或聯絡人列表中的所有使用者。如果鎖定嘗試失敗或伺服器端出現臨時故障,請求可能會返回錯誤代碼EAGAIN。重試時請求很可能會完成。客戶端應用程式必須實施指數輪詢(透過使用者可觸發的立即重試),並且若EAGAIN狀態持續存在或超過幾秒鐘未收到回應,則應通知使用者可能的伺服器或網路問題。
成功執行的請求返回一個結果物件陣列,每個結果出現在與相應指令相同的陣列索引位置。
目標網址:https://g.api.mega.co.nz/cs?id=sequence_number&ak=appkey&[&sid=sessionid|&n=node]
JSON物件應以原始POST請求的有效負載發送。不得進行額外的成幀。不處理Content-Type HTTP標頭,但應設定為application/json。
它的結構是一個指令陣列:[cmd1,cmd2,…]
使用cmd = { a : command type, [argument : value]* }。
對請求的回應是內容類型為application/json的原始JSON物件。
在請求層級錯誤或作為每個指令返回物件的陣列:[res1,res2,…]情況下,它被構建為單一數字(例如,-3表示EAGAIN)
為防止基礎設施過載,動態速率限制生效。在執行請求之前,它包含的指令的總「權重」會根據請求IP位址的當前餘額進行計算和檢查。如果總數超過定義的閾值,請求將被拒絕,並且必須使用指數輪詢演算法重複一遍。
由於伺服器無法可靠地建立與客戶端的連連,因此伺服器-客戶端請求必須由客戶端透過阻塞讀取循環進行輪詢。
目標網址:https://g.api.mega.co.nz/sc?id=sequence_reference[&sid=sessionid|&n=node][ssl=1]
請求層級錯誤以單個數字(例如 -3表示EAGAIN)或內容類型為application/json的原始 JSON物件的形式接收。其結構如下:
{ a : [req1,req2,…], [ sn : sequence_reference | w : wait_url ] }
由於JSON不是二進位乾淨的,因此必須對所有非ASCII資料進行編碼。對於二進位資料,MEGA API使用帶有-_而不是+/的base64變體和尾隨=剝離(必要時,實際有效負載長度在解碼後進行啟發式推斷,例如透過剝離尾隨NUL)。UNICODE文字必須編碼為UTF-8。
MEGA API使用以下主要資料類型:
節點控制代碼的長度為八個字母數字構成的字元,區分大小寫。
使用者控制代碼由11個base64字元組成。
加密金鑰始終採用base64編碼。存在以下金鑰類型:
MEGA使用客戶端加密/解密進行點對點保護檔案的傳輸和儲存。從客戶端那裡收到的資料無遺漏地被儲存和傳輸;伺服器既不進行解密,也不會重新加密,也不會驗證傳入的使用者檔案的加密。所有加密程序都在最終使用者的控制之下進行。
為了允許進行完整性檢查的部分讀取,檔案被視為一系列的區塊。為了簡化伺服器端的處理,部分上傳只能在區塊邊界上開始和結束。此外,如果滿足相同的標準,部分下載只能進行完整性檢查。
區塊邊界位於以下位置:
0 / 128K / 384K / 768K / 1280K / 1920K / 2688K / 3584K / 4608K / …(每1024 KB) / EOF
一個檔案金鑰的長度為 256位元,由以下部分組成:
區塊MAC計算如下(這本質上是CBC-MAC,選擇CBC-MAC而不選擇更有效率的OCB,是出於知識產權考量)
:1h := (n << 64) + n
對於每個AES區塊d為h := AES(k,h XOR d)
區塊使用標準計數器模式進行加密:
對於區塊位置p處的每個AES區塊d為d’ := d XOR AES(k,(n << 64)+p)
MAC計算和加密可以在同一個循環中執行。
解密是類似的。
要獲得meta-MAC m,請將相同的CBC-MAC套用於起始值為0的結果區塊MAC。64位元的meta-MAC m計算為 ((bits 0-31 XOR bits 32-63) << 64) + (bits 64-95 XOR bits 96-127).
上傳是透過將原始資料POSTing到由API u指令返回的目標URL來執行。如果需要,可以分塊執行上傳。區塊可以以任何順序和任何大小發送,但它們必須在區塊邊界上開始和結束。檔案內區塊的位元偏移量x透過將/x附加到URL來表示。多個區塊可以並行發送。當一個區塊完成後,伺服器會回應一個狀態訊息,可以是:
每次上傳的加密金鑰必須由高強度的隨機亂數產生器生成。使用弱的密碼會破壞資料的機密性和完整性。
高延遲連結上的TCP吞吐量受到緩慢的擁塞窗口增長、發送或接收緩衝區大小不足以及(甚至是輕微的)封包遺失的不利影響。所有這些因素都可以透過並行使用多個傳輸連接來緩解。客戶端應用程式為使用者在每個方向提供最多配置六個並行連結。建議的預設值為4。
所有MEGA伺服器都支持HTTPS存取-這是由於許多Web瀏覽器強制執行一項策略,即根本無法從HTTPS頁面發出HTTP請求(IE、Firefox 18以上版本)或至少觸發視覺警告(Chrome、Firefox 17之前版本)。然而,只有兩種類型的請求真正受益而需要HTTPS:https://mega.nz/index.html 的加載和API請求接口。無論是靜態.html和.js組件的雜湊保護加載、等待新的伺服器-客戶端請求、以及已經加密和在儲存叢集之間來往傳輸的MAC資料都沒有從HTTPS中受益。因此,客戶端應用程式需要使用SSL來存取API接口,但在等待請求和批量檔案傳輸時強烈建議不要這樣做。
MEGA的HTTPS存取支援大多數密碼/雜湊,並在SSL相關的地方(例如在根HTML和API伺服器上)使用強大的2048位元的RSA,在不相關的地方(例如靜態HTML和儲存伺服器上)則使用RC4/MD5和節省CPU運算力的1024位元RSA。
PFS(「完美前向保密」)僅在API伺服器上有支援,因為公共靜態內容不需要保密。
最後更新於2020年12月18日,2021年1月18日生效。