JVM日曆:JDPR或Java資料保護建議

Tybyq發表於2018-12-12

在整個技術生態系統中引起反響的一個重大事件是2018年推出的GDPR,即歐洲公民的通用資料保護法規。雖然我將會或不會影響英國公民,但它仍然有待觀察,它為Java開發人員提供了一個積極的機會,可以對三個安全領域感興趣:

  1. 在其應用程式中查詢個人身份資訊(PII)或其他敏感資料。

  2. 正確使用加密技術,以正確保護此資訊和安全系統。

  3. 應用自定義程式碼,庫和JRE的有效補丁管理。

查詢PII和敏感資料

Java開發人員可以透過靜態型別和清除API來定位PII。對於開發人員編寫的POJO的例子,標準化的方法命名透過大部分的社群可以揭示潛在的PII資訊一樣    getAddress() ,    getName() 或    getSomethingElseThatLooksLikePII() 。透過方法名稱,熟悉PII目標的開發人員可以輕鬆找到PII睡眠的興趣點,並識別潛在的洩漏。

Java API還提供了另一種識別PII熊洞穴的簡單方法。例如,大多數永續性由JDBC或ORM庫(如Hibernate)處理。透過觀察查詢或直接檢視資料庫,開發人員可以識別流經這些介面的PII。標準化API(如JDBC和Hibernate)的存在使得基於儀器的工具可以輕鬆地找到PII,類似於免費的基於儀器的工具監控安全性或效能的方式。

正確使用密碼學

Java開發人員受益於Java Cryptographic Architecture,這是一套相容的工具和庫,涵蓋了基本的加密方法。從JDK 9開始,大多數JRE都附帶了Unlimited Strength Cryptography。無限強度的加密強度和策略檔案配置的限制一直是需要強加密的開發專案混淆的根源。Java開發人員提供了一個快速測試,您可以執行以瞭解是否正確配置了無限強度。

匯入 javax。加密。密碼 ;

class  TestCryptoLimitations {

  public  static  void  main(String [] args){

    嘗試 {

      系統。出。println(“Hello World!”);

      int  maxKeyLen  =  密碼。getMaxAllowedKeyLength(“AES”);

      系統。出。println(“最大 金鑰 長度 為 ”  +  maxKeyLen);

    } catch(例外 e){

      系統。出。println(“悲傷的世界:(”);

    }

  }

}


接下來,您可能會在專案中遇到三個主要的加密用例:雜湊檔案/憑證,對稱加密和非對稱加密。

雜湊和訊息摘要

雜湊通常用於生成檔案校驗和或加密憑據。它是一種單向演算法,從金鑰計算雜湊值可以在多項式時間內完成,並且被認為是有效的計算。相反的操作,找到產生給定雜湊的值,稱為碰撞,效率不高且計算成本高。考慮生日攻擊以O(2 ^(n / 2)時間為例。單向雜湊函式的行為使它們適合於憑證儲存或測試資料(例如,檔案)篡改。即使是一個小的改變檔案將顯著更改雜湊值。

常見的雜湊演算法有:SHA-256,SHA-512或較舊的演算法,如MD5和SHA-1,可以在jdk.certpath.disabledAlgorithms屬性下的jre / lib / security / java.security檔案中列入黑名單。

在對憑證的秘密部分進行雜湊(例如,密碼)時,雜湊值應包括每使用者鹽的唯一值。鹽是加密隨機值,難以猜測,通常採用長串十六進位制值或位元組陣列的形式。包含鹽可防止預計算攻擊,攻擊者只需在稱為彩虹表的字典中查詢預先計算的值。不需要Salting來雜湊非秘密資訊,例如檔案檢查。最好使用像PBKDF2這樣的金鑰派生函式而不是自己的憑證雜湊,我們將很快介紹。

計算給定檔案的雜湊值:

MessageDigest  md  =  MessageDigest。getInstance(“SHA - 256 ”);
md。更新(fileinbytes);
final  byte [] hashed  =  md。doFinal();


這可以使用基於密碼的金鑰推導(PBKDF2)來生成資訊的雜湊,這些資訊應該是秘密的並且更難以預先計算。

final  String  password  =  “12345” ;
final  String  salt  =  “user@example.com” ;
final  int  iterations  =  32 ;

PBEKeySpec  keySpec  =  新 PBEKeySpec(密碼。toCharArray(),鹽。的getBytes(),次迭代,512);

SecretKeyFactory  skf  =  SecretKeyFactory。getInstance(“PBKDF2WithHmacSHA256”);

byte [] hashed  =  skf。generateSecret(keySpec)。getEncoded();

final  String  encoded  =  Base64。getEncoder()。encodeToString(hashed);
系統。出。println(“編碼:”  +  編碼);


對稱密碼

對稱密碼用於加密和解密資訊。對稱密碼得名,因為加密和解密操作使用相同的金鑰。對稱密碼術是密碼學的基礎,比非對稱密碼學更快。金鑰通常是長字串或位元組陣列,在字典中不容易找到。

常見的對稱演算法包括AES,Blowfish和DES。以下是對稱加密和解密的示例。

匯入 javax。加密。密碼 ;
匯入 javax。加密。規範。IvParameterSpec ;
匯入 javax。加密。規範。SecretKeySpec ;
匯入 java。安全。SecureRandom ;
匯入 java。util。Base64 ;

public  class  CryptoAdvent {
    public  static  String  encrypt(byte [] key,byte [] initVector,String  value)throws  Exception {
        IvParameterSpec  iv  =  new  IvParameterSpec(initVector);
        SecretKeySpec  skeySpec  =  new  SecretKeySpec(key,“AES”);
        密碼 密碼 =  密碼。getInstance(“AES / CBC / PKCS5PADDING”);
        密碼。INIT(密碼。ENCRYPT_MODE,skeySpec,IV);

        byte [] encrypted  =  cipher。doFinal(值。的getBytes(“UTF-8” ));
        字串 編碼 =  Base64。getEncoder()。encodeToString(加密);
        返回 編碼 ;
    }

    public  static  String  decrypt(byte [] key,byte [] initVector,String  encrypted)throws  Exception {
        IvParameterSpec  iv  =  new  IvParameterSpec(initVector);
        SecretKeySpec  skeySpec  =  new  SecretKeySpec(key,“AES”);
        密碼 密碼 =  密碼。getInstance(“AES / CBC / PKCS5PADDING”);
        密碼。INIT(密碼。DECRYPT_MODE,skeySpec,IV);

        byte [] original  =  cipher。doFinal(Base64的。getDecoder()。解碼(加密));
        return  new  String(original);
    }

    private  static  String  bytesToHex(byte [] bytes){
        StringBuilder  sb  =  new  StringBuilder();
        for(byte  b:bytes){
            SB。追加(字串。格式(“%02X” ,b));
        }
        返回 某人。toString();
    }

    public  static  void  main(String [] args){
        嘗試 {

            //注意:每次程式執行時都會生成一個新的Key和initVector。真實的
            //實現你需要將金鑰和initVector儲存為秘密
            //以後解密。
            //
            SecureRandom  sr  =  new  SecureRandom();
            byte [] key  =  new  byte [ 16 ];
            sr。nextBytes(key); // 128位金鑰
            byte [] initVector  =  new  byte [ 16 ];
            sr。nextBytes(initVector); // 16位元組IV

            系統。出。println(“Random key =” + bytesToHex(key));
            系統。出。println(“initVector =” + bytesToHex(initVector));

            String  payload  =  “這是Erik和Milton的文章的明文。” ;
            系統。出。println(“Original text =” + payload);

            String  encrypted  =  encrypt(key,initVector,payload);
            系統。出。println(“加密文字=” + 加密);

            串 解密 =  解密(鍵,initVector,加密);
            系統。出。println(“Decrypted text =” + decrypted);

            字串 結果 =已 解密。等於(有效載荷)? “有用!” :“事情不對。” ;
            系統。出。println(結果);

        } catch(Exception  t){
            t。printStackTrace();
        }
    }
}


一個示例輸出是:

隨機 鍵= E5  01  B6  AC  9 C  A5  6 D  64  08  DE  AB  DD  83  9 C  E0  87
initVector = AC  09  5 C  B0  6 E  76  3 B  E6  A4  2 B  D7  4 C  B3  4 B  CE  F8
原始 文字= 這 是 在 明文 從 埃裡克 和 米爾頓的文章。
加密 文字= / LQlJp7fR4Gkq5unWU4X + 5 qrje1WWKyCms + MPzcwsFf2eE + QHVr2RQDoJVfrSmoc / dM5ulrtk5z4z4evozprUQ ==
解密 文字= 這 是 在 明文 從 埃裡克 和 米爾頓的文章。
它的 作品!


不對稱密碼

大多數Internet加密(例如HTTPS)都是圍繞非對稱加密構建的。非對稱加密技術的優點在於它為客戶端和伺服器提供了一種安全地協商金鑰和密碼套件的方法,這些秘密金鑰和密碼套件後來用於使用通用的對稱加密技術來保護資料。非對稱加密利用一些新的類,如中   KeyPair ,   PublicKey ,   PrivateKey ,和   Certificate 。這些類中的每一個都設計為可以共享公鑰以便透過不受信任的網路訪問任何人,然後使用他們自己的私鑰加密訊息。然後,公鑰的所有者可以使用他們自己的私鑰解密訊息,使兩者能夠通話。

非對稱加密的最常見用途是與網站進行加密的HTTPS通訊。在這種情況下,每個客戶端都有一個已知的證照頒發機構列表,用於建立身份並驗證每個網站的公鑰的所有者。

與瀏覽器不同,大多數JRE都有一個截斷的證照頒發機構列表,其中包含許多來自Digicert的不同證照,但不包含流行的證照頒發機構,如Amazon Trust(AWS)或SSL.com。因此,Java客戶端可能會因PKIX異常而無法對某些URL進行身份驗證。

發生這種情況時,開發人員不應只是禁用SSL身份驗證。這樣做可以簡單地確保應用程式透過安全通道傳送資訊,而無需知道此通道另一端的內容。

正確的機制是將根證照新增到lib / security / cacerts檔案中:

  keytool -importcert -keystore lib/security/cacerts -alias awstrust -file awstrust.cer

雖然將根證照新增到此根證照頒發機構儲存是合理的,但是耳機之類的東西不需要根證照,如果是,則這些耳機的私鑰應保持私密。

有效的補丁管理

開發人員需要考慮兩個方面進行修補:

  • 保持與JRE的節奏

  • 跟上庫漏洞

Oracle JRE和Amazon Corretto都按季度進行補丁。與Oracle JRE(其Java 8支援在2019年4月結束)不同,Amazon Corretto承諾在2023年之前按季度免費修補補丁 - 大約四年。

Java開發人員無法抵禦最近攻擊Node社群的攻擊型別,從而竊取了不同數量的比特幣。例如,在2014年,針對Maven Central進行了一次攻擊,以修改位元組碼,因為它在jar檔案中移動到網路中。雖然響應很快就能啟用SSL,但大多數JAR檔案仍然沒有透過jarsigner工具簽名,這使得檢測篡改變得更加困難。類似的攻擊在別處發生。

當在第三方庫中發現漏洞時,在部署補丁之前,您的應用程式幾乎沒有防禦。這就是為快速修補設計軟體應用程式,服務和基礎架構對於強大的安全性至關重要的原因。除了快速部署之外,測試通常是一個常見的障礙。大多陣列織推遲修補,因為他們沒有很大的信心推動修補程式不會破壞生產。這就是為什麼投資高質量的單元測試案例非常重要的原因。

為了監控第三方庫的安全狀態,OWASP Dependency Check或Contrast Community Edition等開發人員可以使用免費工具。

許多軟體購買者強制執行這種依賴性分析,稱為軟體組合分析,部分原因是隻需檢視庫就可以輕鬆檢測到。忽視此建議的開發人員可能會發現他們的應用程式取消部署,後續發票未付。

一般建議

開發人員應該關注他們擁有的資料型別以及他們如何保護這些資料。由於GDPR的監管環境,“儲存所有資料”的預設業務方法可能成為嚴重的商業責任。資料可能是新油,但油是易燃的,並且在處理加密資料時,不要將金鑰與加密資料一起儲存,因為這會破壞目的。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31557424/viewspace-2285028/,如需轉載,請註明出處,否則將追究法律責任。

相關文章