簡體   English   中英

更新 Java Card / GlobalPlatform 小程序時如何保留數據?

[英]How to preserve data when updating Java Card / GlobalPlatform applet?

如何更新包含需要跨版本保留的數據的 Java Card 小程序? 據我所知,更新小程序是通過刪除它然后安裝新版本來完成的,這似乎還會刪除與該應用程序關聯的所有持久數據。

作為一個具體的例子,假設我正在編寫一個身份驗證和加密小程序。 小程序的第 1 版將在安裝時生成受硬件保護的密鑰,並支持對消息進行簽名,但不對其進行加密。 假設然后我想發布一個也支持加密的版本 2,並且可以使用版本 1 創建的密鑰。我需要在版本 1 和 2 中做什么才能使這成為可能?

除了純 Java Card 之外,我對使用 GlobalPlatform 機制的解決方案持開放態度。

您需要第二個小程序,該小程序擁有要在重新安裝第一個小程序時保留的所有對象。 我們稱它們為存儲小程序和工人小程序。

這意味着每次 Worker 小程序需要使用來自 Storage 小程序的資源時,它都必須調用 Shareable 接口。 代碼大小、代碼可維護性和速度都會受到影響。 我想不出在 Java Card 或 Global Platform 中執行此操作的另一種方法。

你不能。

在當前的 JavaCard 智能卡上,更新應用程序包的同時保留與從該包實例化的任何小程序關聯的數據是不可能的。

一方面,這有一個相當簡單的技術原因:

小程序是從應用程序包的代碼庫中的類實例化的 Java(卡片)對象。 更新代碼庫會改變類的結構,因此,已經實例化的小程序對象將不再匹配它們的類定義。 因此,每當應用程序包中的小程序類發生變化時,這也意味着需要重新創建相應的小程序實例。

由於所有小程序數據本身都組織為 Java (Card) 對象(例如從用戶定義的類、數組或原始類型字段實例化的對象,這些對象存儲為小程序實例的直接或間接屬性,因此小程序實例是其所有關聯數據的根元素1。因此,刪除和重新創建該根實例的必要性也意味着源自該根元素的數據被刪除並重新初始化。

當然,這可以通過使小程序(以及存儲小程序數據的所有子對象)可序列化來克服。 這樣,小程序可以在更新其代碼庫之前序列化到輔助存儲區。 更新后,可以通過反序列化該數據來重新創建小程序實例(及其對象層次結構)。 但是,允許這樣做會產生嚴重的安全隱患:任何管理實例都可以序列化(並且在最壞的情況下提取)該數據。

這讓我想到了第二個原因:在我看來(雖然我找不到任何權威資源),Java Card 平台和智能卡的中心設計原則是防止提取敏感數據。

考慮以下示例:您有一個用於數字簽名的小程序(例如 PIV、OpenPGP,或者只是您在問題中描述的小程序)。 此小程序的目的是將密鑰安全地存儲在智能卡芯片上(具有保護功能的專用硬件,即使攻擊者獲得對物理卡/芯片的訪問權限,也禁止物理提取密鑰材料)。 因此,小程序安全地在芯片上生成其私鑰材料。 然后可以使用秘密私鑰進行簽名(和/或解密),但絕不應該允許它離開卡(因為這會導致密鑰/卡復制、密鑰泄露給攻擊者等)

現在想象一下,智能卡運行時環境允許對包括秘密私鑰在內的小程序數據進行序列化。 即使卡不提供任何直接提取序列化數據的方法,只需考慮攻擊者編寫一個與您自己的小程序具有完全相同結構的新小程序,除了它提供了一種從卡中提取密鑰材料的附加方法. 攻擊者現在創建一個應用程序包,表明它是對現有小程序的更新。 進一步假設攻擊者能夠在卡上加載該應用程序包。 現在攻擊者能夠更新您的小程序並破壞您的原始設計目標(使其無法從卡中提取密鑰)。

覆蓋現有應用程序/小程序需要擦除現有小程序及其所有數據的設計原則也(在某種程度上)體現在 GlobalPlatform Card 規范和 Java Card Runtime 規范中:

GlobalPlatform卡規范,2.3 版,2015 年 10 月:

  • 使用 INSTALL [for load] 命令加載任何應用程序包時,OPEN 需要

    “檢查加載文件的 AID 是否已作為可執行加載文件或應用程序存在於 GlobalPlatform 注冊表中。”

  • 使用 INSTALL [for install] 命令安裝小程序實例時,OPEN 需要

    “檢查應用程序 AID [...] 是否已作為應用程序或可執行加載文件存在於 GlobalPlatform 注冊表中”

  • Java Card 3 平台,運行時環境規范,經典版,版本 3.0.4,2011 年 9 月:

    “Java Card RE 應保證在以下情況下不會認為小程序安裝成功:

    • 由包 AID 標識的小程序包已經駐留在卡上。
    • 小程序包包含一個小程序,該小程序與卡上已駐留的另一個小程序具有相同的 Java Card 平台名稱。”

    此外,規范明確指出小程序刪除必須刪除小程序實例擁有的所有對象:

    “Applet 實例刪除涉及刪除 Applet 對象實例和 Applet 實例擁有的對象以及相關聯的 Java Card RE 結構。”

然而,有時可能有正當理由使應用程序的某些部分可在不擦除密鑰等信息的情況下進行更新,並且有一些方法可以解決此問題:

  • 芯片和卡操作系統制造商可能確實有辦法在現有卡上修補卡操作系統和運行時環境的某些功能。 我無法通過任何權威來源引用此假設。
  • 如果您從一開始就將補丁/可升級性視為設計目標,那么您肯定能夠以這樣一種方式設計您的應用程序,即可以在不丟失相關數據的情況下升級部分應用程序。 您通常會將應用程序拆分為多個應用程序包,其中包含應用程序功能的不同部分(另請參閱Shuckey 的回答)。 在最簡單的形式中,一個小程序將包含和管理所有業務邏輯,而另一個小程序(它需要在一個單獨的應用程序包中)負責存儲敏感的持久數據。 然后,您可以使用可共享接口從業務邏輯小程序訪問存儲在數據存儲小程序中的數據。

    但是,您肯定希望精心設計兩個實例之間的接口。 例如,您絕對不想直接傳遞秘密私鑰。 相反,您只想共享一個接口來對從業務邏輯小程序傳遞到數據存儲小程序的數據執行簽名/解密操作。 否則,將出現與上述相同的提取問題。


1 ) 這不一定總是正確的,因為數據可能(技術上)存儲在靜態字段中。 在這種情況下,應用程序包將是這些元素的根。 但是,這樣做會對安全性產生嚴重影響,因為對靜態字段的訪問不受小程序隔離/小程序防火牆的保護。 參見 Java Card 3 Platform, Runtime Environment Specification, Classic Edition , Version 3.0.4, Sept. 2011, sect. 6.1.6:

“當訪問類靜態字段時,沒有可以執行的運行時上下文檢查。”

GlobalPlatform Amendment H Card Executable Load File Update 為這個問題提供了解決方案。 https://globalplatform.org/wp-content/uploads/2018/03/GPC_2.3_H_ELF_Upgrade_v1.1_PublicRelease.pdf )。 但是我不知道市場上是否已經有實現此規范的產品。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM