GrowingIO 數據安全實踐

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"什麼是數據安全","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"根據《中華人民共和國數據安全法》中第三條,給出了數據安全的定義,是指通過採取必要措施,確保數據處於有效保護和合法利用的狀態,以及具備保障持續安全狀態的能力。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"爲什麼企業要做數據安全","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在互聯網盛行的今天,不法分子可以通過網絡攻擊,網絡欺騙等手段竊取用戶的個人信息甚至企業的機密信息。而且在拿到部分用戶信息後就可以唯一的鎖定具體某一個人,因此數據的保密顯得格外重要。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"GrowingIO 數據安全落地","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了保證客戶數據的安全性, GrowingIO 通過構建一個安全的軟件運行時與數據靜態存儲加密來提高數據生產安全性。下面我們將詳細介紹數據安全落地的過程。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"【軟件運行安全","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"軟件運行安全也就是企業的系統運行安全,這主要包含兩個方面: 數據邏輯隔離:系統通過用戶的權限與角色,給出專有的數據操作集合。 KMS祕鑰管理:系統所依賴的數據庫,中間件不會因爲祕鑰的泄露而造成數據泄露。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"數據邏輯隔離","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據邏輯隔離主要是對平臺上操作的用戶進行身份,角色,權限的認證。 認證流程:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/2c/2cbc7afdbcb2fe50e5367a9059b0c7f1.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所有平臺的用戶通過RBAC 權限模型分配不同的角色和權限。只有擁有對應角色權限的用戶才能查看或進行對應的操作。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"KMS 祕鑰管理","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"KMS 即(key manage system)祕鑰管理系統。目前亞馬遜雲和阿里雲等雲產品都有自己的解決方案。KMS 支持多種類型的的數據庫,中間件,以及應用祕鑰管理等功能。使用KMS 之後所有數據庫,中間件等的用戶名,密碼對產研均不可見,應用靜態數據加密對應的祕鑰也不可見。 目前支持數據庫和中間件以及系統祕鑰:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/2b/2b8fa77c21b501df287bb0dc7f11f1c0.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 【","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"交互流程】","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/29/29dbcbab7e8d8be9511fd826aef7f486.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 【","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"示例展示】","attrs":{}},{"type":"text","text":" 以亞馬遜雲(AWS)爲例: ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"應用配置","attrs":{}}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"kms:\n enabled: false\n aws:\n region: \"\"\n access_key_id: \"\"\n secret_access_key: \"\"\n#應用中添加\nspring:\n redis:\n kms-key: \"test/json/redis\"\n datasource:\n kms-key: \"test/postgresql/accounts\"","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"運行初始化","attrs":{}},{"type":"text","text":" 示例以postgresql 數據庫HikariCP 連接池爲例:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"@Bean\n@ConditionalOnProperty(value = \"kms.enabled\",havingValue = \"true\")\npublic HikariDataSource dataSource(DataSourceProperties properties, KmsProperties kms,Configs configs) {\n SecretsManagerClient client = SecretsManagerClientBuilder.build(kms.getRegion(),kms.getAwsAccessKeyId(),kms.getAwsSecretAccessKey());\n AwsSecretProvider secretProvider = new AwsSecretProvider(client);\n String secret;\n try{\n secret = secretProvider.getSecret(configs.getDataSourceKmsKey());\n //secret是json格式的鏈接信息\n final HashMap map = Jackson.readValue(secret, HashMap.class);\n String url = String.format(\"jdbc:postgresql://%s:%s/%s?useUnicode=true&useSSL=false&characterEncoding=utf8\",map.get(\"host\"),map.get(\"port\"),map.get(\"dbname\"));\n properties.setUrl(url);\n properties.setUsername(map.get(\"username\"));\n properties.setPassword(map.get(\"password\"));\n }catch (Exception e) {\n log.error(\"kms database error\",e);\n }\n HikariDataSource dataSource = properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();\n if (StringUtils.hasText(properties.getName())) {\n dataSource.setPoolName(properties.getName());\n }\n return dataSource;\n }","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在實際開發中用到的任何數據庫,中間件都可以通過KMS 來管理對應的用戶名,密碼等敏感信息。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"【靜態存儲安全】","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"PII 管理","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"【什麼是PII】","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PII 即個人身份信息 (Personally identifiable information) 是任何可能識別特定個人的數據。任何可用於將一個人與另一個人區分開來並可用於對以前匿名數據進行去匿名化的信息都可以被視爲 PII。 PII 可以單獨使用或與其他相關數據一起使用來識別個人,並且包含可以唯一識別個人的直接標識符(例如護照信息)或準標識符(例如種族),可以與其他準標識符結合使用標識符,如出生日期,以成功識別個人。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"【","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"PII 意義】","attrs":{}},{"type":"text","text":" ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"保護 PII 對於個人隱私、數據隱私、數據保護、信息隱私和信息安全至關重要。僅憑個人信息的一小部分,竊賊就可以以該人的名義創建虛假賬戶、產生債務、僞造護照或將個人身份出售給犯罪分子。隨着個人的個人數據每天被記錄、跟蹤和使用——例如在使用指紋的生物識別掃描和用於解鎖設備的面部識別系統中——保護個人身份和他們獨有的任何識別信息變得越來越重要。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"【PII 加解密】","attrs":{}},{"type":"text","text":" ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PII 加密: 對於所有入庫的用戶敏感數據使用加密算法進行加密。 PII 解密:普通用戶只能查看加密的密文數據,對於有業務需要的通過授權可以查看明文數據。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"GrowingIO 默認選擇AES(AES/CBC/PKCS5Padding) 算法 ,採用256長度的祕鑰來作爲PII 數據加密的實現。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"執行流程","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據加密","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/31/31abeaa3d06a59204d2982a4d831ff2c.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"數據解密","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/00/0059f0d5fef6d7becdbf4aecbfeeb3fd.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"示例展示","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PII 可以從配置中心或KMS 中來獲取加解密需要的祕鑰數據。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"祕鑰獲取:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"// KMS 方式\nSecretsManagerClient client = SecretsManagerClientBuilder.build(kms.getRegion(),kms.getAwsAccessKeyId(),kms.getAwsSecretAccessKey());\nAwsSecretProvider secretProvider = new AwsSecretProvider(client);\nString secret = secretProvider.getSecret(\"test/pii/json\");\n//secret是json格式的鏈接信息\nfinal HashMap map = Jackson.readValue(secret, HashMap.class);\n\nString algorithmIv = map.getOrElse(\"algorithm_iv\", \"\");\n// 向量\nString iv = DatatypeConverter.parseHexBinary(algorithmIv);\n// 祕鑰\nString encryptionKey = DatatypeConverter.parseHexBinary(map(\"encryption_key\"));\nString decryptionKey = DatatypeConverter.parseHexBinary(map(\"decryption_key\"));\n\n// 配置中心方式\n// 向量\nString iv = Hex.decodeHex(Configs.Encry.configCenterIv);\n// 祕鑰\nString secret = Hex.decodeHex(Configs.Encry.configCenterSecret);","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"執行加密或者解密操作:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過PII 進行數據處理後,數據庫中敏感數據全爲加密存儲。頁面渲染依據用戶權限判斷是否加密或者解密展示。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"數據存儲與渲染","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據庫數據:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/bf/bf809aca431830ccaacbae2c469f5a27.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"只有管理員登錄後渲染解密後的數據:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/10/1000b5e81f983bb0728b2825676f555c.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"常見問題","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 一、向量IV 的支持","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"在AES 加密算法中:AES_ECB_PKCS5Padding 不支持向量,AES_CBC_PKCS5Padding支持向量且安全性更高。如果原來已經有用到AES 算法要考慮兼容性。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"二、Base 64 編碼帶來的問題","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現象:如果加密的字符串比較長,加密後的密文將長度超過76時,密文中會被加入一個換行符,導致後續按行解析異常。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在JDK1.8 之後Base64 工具類移到了java.util 包中,爲了向低版本的JDK 兼容,Base64 中 MimeEncode,採用的方式:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"private static final int MIMELINEMAX = 76;\nprivate static final byte[] CRLF = new byte[] {'\\r', '\\n'};\nstatic final Encoder RFC2045 = new Encoder(false, CRLF, MIMELINEMAX, true);","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是說在加密串的長度超過76時會加上 '\\r' 或者 '\\n',這就導致如果按行進行數據的某些操作將會發生致命錯誤。所以推薦使用Base64中Encode的實現:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"static final Encoder RFC4648 = new Encoder(false, null, -1, true);\nstatic final Encoder RFC4648_URLSAFE = new Encoder(true, null, -1, true);","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這樣不管加密後的字符串長度有多長都不會發生換行的問題。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"參考JDK 源碼和祕鑰標準: ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"RFC 4648","attrs":{}},{"type":"text","text":" ","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"http://www.ietf.org/rfc/rfc4648.txt ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"RFC 2045 http://www.ietf.org/rfc/rfc2045.txt","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章