加密数据和数据库连接

在Greenplum数据库系统中可以用下面的方式使用加密来保护数据:

  • 客户端和Master数据库之间的连接可以用SSL加密。这种方式可以通过设置ssl服务器配置参数为on并且编辑pg_hba.conf文件来启用。有关在Greenplum数据库中启用SSL的信息请见Greenplum数据库管理员指南中的“加密客户端/服务器连接”。
  • Greenplum数据库4.2.1及以上的版本允许在Greenplum的并行文件分发服务器、gpfdist和Segment主机之间传输SSL加密数据。详见加密gpfdist连接
  • Greenplum数据库集群中主机之间的网络通信可以使用IPsec加密。集群中的每一对主机之间会建立一个认证过的加密的VPN。对IPsec的支持请检查操作系统文档,或者考虑Zettaset等组织提供的第三方解决方案。
  • pgcrypto包中的加密/解密函数保护停留在数据库中的数据。列级的加密可以保护敏感信息,例如口令、社会保险号码或者信用卡号码。例子可以在使用PGP加密表中的数据中找到。

最佳实践

  • 加密确保数据只能被拥有解密数据所需密钥的用户看见。
  • 加密和解密数据有性能代价,只加密需要加密的数据。
  • 在生产系统中实现任何加密解决方案之前先做性能测试。
  • 用于生产的Greenplum数据库系统中的服务器证书应该由一个数字证书认证机构(CA)签发,这样客户端可以认证服务器。如果所有的客户端都在该组织本地,这个CA可以是本地的。
  • 只要到Greenplum数据库的客户端连接会通过一个不安全的链路,就应该使用SSL加密。
  • 对称加密模式(加密和解密使用相同的密钥)比非对称模式具有更好的性能,并且应该在可以安全共享密钥时使用对称模式。
  • 使用来自pgcrypto包的函数来加密磁盘上的数据。数据在数据库进程中被加密和解密,因此有必要用SSL来保护客户端连接以避免传输未加密的数据。
  • 在ETL数据被载入数据库或者被从数据库中卸载时,使用gpfdists协议来保护ETL数据。请见加密gpfdist连接

密钥管理

只要使用对称(单私钥)或者非对称(公钥和私钥)加密,就有必要安全地存储主密钥或者私钥。存储加密密钥有很多选项,例如在文件系统上保存、密钥保管库、加密的USB、可信平台模块(TPM)或者硬件安全模块(HSM)。

在规划密钥管理时考虑下列问题:

  • 密钥将被存在哪里?
  • 密钥何时过期?
  • 如何保护密钥?
  • 如何访问密钥?
  • 如何恢复和收回密钥?

开放Web应用安全性项目(OWASP)提供了一套非常全面的保护加密密钥指南

用pgcrypto加密静止数据

Greenplum数据库的pgcrypto包提供了加密数据库中静止数据的函数。管理员可以加密具有敏感信息(例如社会保险号码或信用卡号)的列以提供一个额外的保护层。没有加密密钥的用户无法读取以加密形式存储的数据库数据,并且这些数据也无法从磁盘直接读取。

pgcrypto允许使用对称和非对称加密的PGP加密。对称加密使用同样的密钥加密和解密数据,并且比非对称加密更快。在交换密钥不成问题的环境中它是首选方法。在非对称加密中,公钥被用来加密数据而私钥被用来解密数据。这种模式比对称加密慢一些并且要求更强的密钥。

使用pgcrypto总是会带来性能和可维护性的代价。有必要只对需要加密的数据使用加密。还有,要记住用户无法通过索引加密数据来搜索它们。

在用户实现数据库内加密之前,考虑下列PGP限制。

  • 不支持签名。这还意味着不会检查加密子密钥是否属于主密钥。
  • 不支持将加密密钥作为主密钥。这种做法通常是不被鼓励的,因此这一限制应该不是问题。
  • 不支持多个子密钥。这可能看起来像一个问题,因为这是一种常见的做法。在另一方面,用户不应将其常规GPG/PGP密钥用于pgcrypto,而是要创建新的密钥,因为使用场景不同。

Greenplum数据库默认用zlib编译,这允许PGP加密函数在加密数据之前先压缩数据。在编译有OpenSSL时,将会有更多算法可用。

因为pgcrypto函数运行在数据库服务器内部,数据和口令是以明文形式在pgcrypto和客户端应用之间移动。为了最好的安全性,用户应该使用本地连接或者使用SSL连接,并且用户应该信任系统管理员和数据库管理员。

Greenplum数据库默认没有安装pgcrypto包。用户可以从Pivotal Network下载一个pgcrypto包,并且使用Greenplum包管理器(gppkg)在集群中安装pgcrypto。

pgcrypto会根据主PostgreSQL配置脚本的发现配置自身。

当编译有zlib时,pgcrypto加密函数能在加密前压缩数据。

pgcrypto拥有从基本内建函数到高级内建函数的多个加密级别。下面的表格展示了支持的加密算法。

表 1. pgcrypto支持的加密函数
值功能内建带有OpenSSL
MD5
SHA1
SHA224/256/384/5121.
其他摘要算法2
Blowfish
AES3
DES/3DES/CAST5
原始加密
PGP对称密钥
PGP公钥

创建PGP密钥

要在Greenplum数据库中使用PGP非对称加密,用户必须首先创建公私钥并且安装它们。

这一节假定用户正在Linux机器上用Gnu Privacy Guard(gpg)命令行工具安装Greenplum数据库。Pivotal推荐使用最新版本的GPG来创建密钥。可以从https://www.gnupg.org/download/为用户的操作系统下载并安装Gnu Privacy Guard(GPG)。在GnuPG网站上,用户将找到用于常见Linux发行的安装器以及Windows和Mac OS X安装器的链接。

  1. 作为root,执行下列命令并且从菜单选择选项1:

    1. # gpg --gen-key
    2. gpg (GnuPG) 2.0.14; Copyright (C) 2009 Free Software Foundation, Inc.
    3. This is free software: you are free to change and redistribute it.
    4. There is NO WARRANTY, to the extent permitted by law.
    5. gpg: directory `/root/.gnupg' created
    6. gpg: new configuration file `/root/.gnupg/gpg.conf' created
    7. gpg: WARNING: options in `/root/.gnupg/gpg.conf' are not yet active during this run
    8. gpg: keyring `/root/.gnupg/secring.gpg' created
    9. gpg: keyring `/root/.gnupg/pubring.gpg' created
    10. Please select what kind of key you want:
    11. (1) RSA and RSA (default)
    12. (2) DSA and Elgamal
    13. (3) DSA (sign only)
    14. (4) RSA (sign only)
    15. Your selection? 1
  2. 如下例所示,回应提示并且遵循其指导:

    1. RSA keys may be between 1024 and 4096 bits long.
    2. What keysize do you want? (2048) Press enter to accept default key size
    3. Requested keysize is 2048 bits
    4. Please specify how long the key should be valid.
    5. 0 = key does not expire
    6. <n> = key expires in n days
    7. <n>w = key expires in n weeks
    8. <n>m = key expires in n months
    9. <n>y = key expires in n years
    10. Key is valid for? (0) 365
    11. Key expires at Wed 13 Jan 2016 10:35:39 AM PST
    12. Is this correct? (y/N) y
    13. GnuPG needs to construct a user ID to identify your key.
    14. Real name: John Doe
    15. Email address: jdoe@email.com
    16. Comment:
    17. You selected this USER-ID:
    18. "John Doe <jdoe@email.com>"
    19. Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
    20. You need a Passphrase to protect your secret key.
    21. (For this demo the passphrase is blank.)
    22. can't connect to `/root/.gnupg/S.gpg-agent': No such file or directory
    23. You don't want a passphrase - this is probably a *bad* idea!
    24. I will do it anyway. You can change your passphrase at any time,
    25. using this program with the option "--edit-key".
    26. We need to generate a lot of random bytes. It is a good idea to perform
    27. some other action (type on the keyboard, move the mouse, utilize the
    28. disks) during the prime generation; this gives the random number
    29. generator a better chance to gain enough entropy.
    30. We need to generate a lot of random bytes. It is a good idea to perform
    31. some other action (type on the keyboard, move the mouse, utilize the
    32. disks) during the prime generation; this gives the random number
    33. generator a better chance to gain enough entropy.
    34. gpg: /root/.gnupg/trustdb.gpg: trustdb created
    35. gpg: key 2027CC30 marked as ultimately trusted
    36. public and secret key created and signed.
    37. gpg: checking the trustdbgpg:
    38. 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
    39. gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
    40. gpg: next trustdb check due at 2016-01-13
    41. pub 2048R/2027CC30 2015-01-13 [expires: 2016-01-13]
    42. Key fingerprint = 7EDA 6AD0 F5E0 400F 4D45 3259 077D 725E 2027 CC30
    43. uid John Doe <jdoe@email.com>
    44. sub 2048R/4FD2EFBB 2015-01-13 [expires: 2016-01-13]
  3. 通过输入下列命令来列出PGP密钥:

    1. gpg --list-secret-keys
    2. /root/.gnupg/secring.gpg
    3. ------------------------
    4. sec 2048R/2027CC30 2015-01-13 [expires: 2016-01-13]
    5. uid John Doe <jdoe@email.com>
    6. ssb 2048R/4FD2EFBB 2015-01-13

    2027CC30是公钥并且将被用来加密数据库中的数据。4FD2EFBB是私钥并且将被用来解密数据。

  4. 使用下列命令导出密钥:

    1. # gpg -a --export 4FD2EFBB > public.key
    2. # gpg -a --export-secret-keys 2027CC30 > secret.key

更多有关PGP加密函数的信息请见pgcrypto文档。

使用PGP加密表中的数据

这个小节展示如何使用用户产生的PGP密钥加密插入到一列中的数据。

  1. 转储public.key文件的内容,然后把它拷贝的剪贴板:

    1. # cat public.key
    2. -----BEGIN PGP PUBLIC KEY BLOCK-----
    3. Version: GnuPG v2.0.14 (GNU/Linux)
    4. mQENBFS1Zf0BCADNw8Qvk1V1C36Kfcwd3Kpm/dijPfRyyEwB6PqKyA05jtWiXZTh
    5. 2His1ojSP6LI0cSkIqMU9LAlncecZhRIhBhuVgKlGSgd9texg2nnSL9Admqik/yX
    6. R5syVKG+qcdWuvyZg9oOOmeyjhc3n+kkbRTEMuM3flbMs8shOwzMvstCUVmuHU/V
    7. vG5rJAe8PuYDSJCJ74I6w7SOH3RiRIc7IfL6xYddV42l3ctd44bl8/i71hq2UyN2
    8. /Hbsjii2ymg7ttw3jsWAx2gP9nssDgoy8QDy/o9nNqC8EGlig96ZFnFnE6Pwbhn+
    9. ic8MD0lK5/GAlR6Hc0ZIHf8KEcavruQlikjnABEBAAG0HHRlc3Qga2V5IDx0ZXN0
    10. a2V5QGVtYWlsLmNvbT6JAT4EEwECACgFAlS1Zf0CGwMFCQHhM4AGCwkIBwMCBhUI
    11. AgkKCwQWAgMBAh4BAheAAAoJEAd9cl4gJ8wwbfwH/3VyVsPkQl1owRJNxvXGt1bY
    12. 7BfrvU52yk+PPZYoes9UpdL3CMRk8gAM9bx5Sk08q2UXSZLC6fFOpEW4uWgmGYf8
    13. JRoC3ooezTkmCBW8I1bU0qGetzVxopdXLuPGCE7hVWQe9HcSntiTLxGov1mJAwO7
    14. TAoccXLbyuZh9Rf5vLoQdKzcCyOHh5IqXaQOT100TeFeEpb9TIiwcntg3WCSU5P0
    15. DGoUAOanjDZ3KE8Qp7V74fhG1EZVzHb8FajR62CXSHFKqpBgiNxnTOk45NbXADn4
    16. eTUXPSnwPi46qoAp9UQogsfGyB1XDOTB2UOqhutAMECaM7VtpePv79i0Z/NfnBe5
    17. AQ0EVLVl/QEIANabFdQ+8QMCADOipM1bF/JrQt3zUoc4BTqICaxdyzAfz0tUSf/7
    18. Zro2us99GlARqLWd8EqJcl/xmfcJiZyUam6ZAzzFXCgnH5Y1sdtMTJZdLp5WeOjw
    19. gCWG/ZLu4wzxOFFzDkiPv9RDw6e5MNLtJrSp4hS5o2apKdbO4Ex83O4mJYnav/rE
    20. iDDCWU4T0lhv3hSKCpke6LcwsX+7liozp+aNmP0Ypwfi4hR3UUMP70+V1beFqW2J
    21. bVLz3lLLouHRgpCzla+PzzbEKs16jq77vG9kqZTCIzXoWaLljuitRlfJkO3vQ9hO
    22. v/8yAnkcAmowZrIBlyFg2KBzhunYmN2YvkUAEQEAAYkBJQQYAQIADwUCVLVl/QIb
    23. DAUJAeEzgAAKCRAHfXJeICfMMOHYCACFhInZA9uAM3TC44l+MrgMUJ3rW9izrO48
    24. WrdTsxR8WkSNbIxJoWnYxYuLyPb/shc9k65huw2SSDkj//0fRrI61FPHQNPSvz62
    25. WH+N2lasoUaoJjb2kQGhLOnFbJuevkyBylRz+hI/+8rJKcZOjQkmmK8Hkk8qb5x/
    26. HMUc55H0g2qQAY0BpnJHgOOQ45Q6pk3G2/7Dbek5WJ6K1wUrFy51sNlGWE8pvgEx
    27. /UUZB+dYqCwtvX0nnBu1KNCmk2AkEcFK3YoliCxomdOxhFOv9AKjjojDyC65KJci
    28. Pv2MikPS2fKOAg1R3LpMa8zDEtl4w3vckPQNrQNnYuUtfj6ZoCxv
    29. =XZ8J
    30. -----END PGP PUBLIC KEY BLOCK-----
  2. 创建一个名为userssn的表并且插入一些敏感数据,这个例子中是Bob和Alice的社会保险号码。在”dearmor(“之后粘贴public.key的内容。

    1. CREATE TABLE userssn( ssn_id SERIAL PRIMARY KEY,
    2. username varchar(100), ssn bytea);
    3. INSERT INTO userssn(username, ssn)
    4. SELECT robotccs.username, pgp_pub_encrypt(robotccs.ssn, keys.pubkey) AS ssn
    5. FROM (
    6. VALUES ('Alice', '123-45-6788'), ('Bob', '123-45-6799'))
    7. AS robotccs(username, ssn)
    8. CROSS JOIN (SELECT dearmor('-----BEGIN PGP PUBLIC KEY BLOCK-----
    9. Version: GnuPG v2.0.14 (GNU/Linux)
    10. mQENBFS1Zf0BCADNw8Qvk1V1C36Kfcwd3Kpm/dijPfRyyEwB6PqKyA05jtWiXZTh
    11. 2His1ojSP6LI0cSkIqMU9LAlncecZhRIhBhuVgKlGSgd9texg2nnSL9Admqik/yX
    12. R5syVKG+qcdWuvyZg9oOOmeyjhc3n+kkbRTEMuM3flbMs8shOwzMvstCUVmuHU/V
    13. vG5rJAe8PuYDSJCJ74I6w7SOH3RiRIc7IfL6xYddV42l3ctd44bl8/i71hq2UyN2
    14. /Hbsjii2ymg7ttw3jsWAx2gP9nssDgoy8QDy/o9nNqC8EGlig96ZFnFnE6Pwbhn+
    15. ic8MD0lK5/GAlR6Hc0ZIHf8KEcavruQlikjnABEBAAG0HHRlc3Qga2V5IDx0ZXN0
    16. a2V5QGVtYWlsLmNvbT6JAT4EEwECACgFAlS1Zf0CGwMFCQHhM4AGCwkIBwMCBhUI
    17. AgkKCwQWAgMBAh4BAheAAAoJEAd9cl4gJ8wwbfwH/3VyVsPkQl1owRJNxvXGt1bY
    18. 7BfrvU52yk+PPZYoes9UpdL3CMRk8gAM9bx5Sk08q2UXSZLC6fFOpEW4uWgmGYf8
    19. JRoC3ooezTkmCBW8I1bU0qGetzVxopdXLuPGCE7hVWQe9HcSntiTLxGov1mJAwO7
    20. TAoccXLbyuZh9Rf5vLoQdKzcCyOHh5IqXaQOT100TeFeEpb9TIiwcntg3WCSU5P0
    21. DGoUAOanjDZ3KE8Qp7V74fhG1EZVzHb8FajR62CXSHFKqpBgiNxnTOk45NbXADn4
    22. eTUXPSnwPi46qoAp9UQogsfGyB1XDOTB2UOqhutAMECaM7VtpePv79i0Z/NfnBe5
    23. AQ0EVLVl/QEIANabFdQ+8QMCADOipM1bF/JrQt3zUoc4BTqICaxdyzAfz0tUSf/7
    24. Zro2us99GlARqLWd8EqJcl/xmfcJiZyUam6ZAzzFXCgnH5Y1sdtMTJZdLp5WeOjw
    25. gCWG/ZLu4wzxOFFzDkiPv9RDw6e5MNLtJrSp4hS5o2apKdbO4Ex83O4mJYnav/rE
    26. iDDCWU4T0lhv3hSKCpke6LcwsX+7liozp+aNmP0Ypwfi4hR3UUMP70+V1beFqW2J
    27. bVLz3lLLouHRgpCzla+PzzbEKs16jq77vG9kqZTCIzXoWaLljuitRlfJkO3vQ9hO
    28. v/8yAnkcAmowZrIBlyFg2KBzhunYmN2YvkUAEQEAAYkBJQQYAQIADwUCVLVl/QIb
    29. DAUJAeEzgAAKCRAHfXJeICfMMOHYCACFhInZA9uAM3TC44l+MrgMUJ3rW9izrO48
    30. WrdTsxR8WkSNbIxJoWnYxYuLyPb/shc9k65huw2SSDkj//0fRrI61FPHQNPSvz62
    31. WH+N2lasoUaoJjb2kQGhLOnFbJuevkyBylRz+hI/+8rJKcZOjQkmmK8Hkk8qb5x/
    32. HMUc55H0g2qQAY0BpnJHgOOQ45Q6pk3G2/7Dbek5WJ6K1wUrFy51sNlGWE8pvgEx
    33. /UUZB+dYqCwtvX0nnBu1KNCmk2AkEcFK3YoliCxomdOxhFOv9AKjjojDyC65KJci
    34. Pv2MikPS2fKOAg1R3LpMa8zDEtl4w3vckPQNrQNnYuUtfj6ZoCxv
    35. =XZ8J
    36. -----END PGP PUBLIC KEY BLOCK-----' AS pubkey) AS keys;
  3. 验证ssn列被加密。

    1. test_db=# select * from userssn;
    2. ssn_id | 1
    3. username | Alice
    4. ssn | \301\300L\003\235M%_O\322\357\273\001\010\000\272\227\010\341\216\360\217C\020\261)_\367
    5. [\227\034\313:C\354d<\337\006Q\351('\2330\031lX\263Qf\341\262\200\3015\235\036AK\242fL+\315g\322
    6. 7u\270*\304\361\355\220\021\330"\200%\264\274}R\213\377\363\235\366\030\023)\364!\331\303\237t\277=
    7. f \015\004\242\231\263\225%\032\271a\001\035\277\021\375X\232\304\305/\340\334\0131\325\344[~\362\0
    8. 37-\251\336\303\340\377_\011\275\301/MY\334\343\245\244\372y\257S\374\230\346\277\373W\346\230\276\
    9. 017fi\226Q\307\012\326\3646\000\326\005:E\364W\252=zz\010(:\343Y\237\257iqU\0326\350=v0\362\327\350\
    10. 315G^\027:K_9\254\362\354\215<\001\304\357\331\355\323,\302\213Fe\265\315\232\367\254\245%(\\\373
    11. 4\254\230\331\356\006B\257\333\326H\022\013\353\216F?\023\220\370\035vH5/\227\344b\322\227\026\362=\
    12. 42\033\322<\001}\243\224;)\030zqX\214\340\221\035\275U\345\327\214\032\351\223c\2442\345\304K\016\
    13. 011\214\307\227\237\270\026`R\205\205a~1\263\236[\037C\260\031\205\374\245\317\033k|\366\253\037
    14. ---------+--------------------------------------------------------------------------------------------
    15. ------------------------------------------------------------------------------------------------------
    16. ------------------------------------------------------------------------------------------------------
    17. ------------------------------------------------------------------------------------------------------
    18. ------------------------------------------------------------------------------------------------------
    19. ------------------------------------------------------------------------------------------------------
    20. ------------------------------------------------------------------------------------------------------
    21. ------------------------------------------------------------------------------------------------------
    22. ------------------------------------------------------------------------------------------------------
    23. ------------------------------------------------------------------------------
    24. ssn_id | 2
    25. username | Bob
    26. ssn | \301\300L\003\235M%_O\322\357\273\001\007\377t>\345\343,\200\256\272\300\012\033M4\265\032L
    27. L[v\262k\244\2435\264\232B\357\370d9\375\011\002\327\235<\246\210b\030\012\337@\226Z\361\246\032\00
    28. 7`\012c\353]\355d7\360T\335\314\367\370;X\371\350*\231\212\260B\010#RQ0\223\253c7\0132b\355\242\233\34
    29. 1\000\370\370\366\013\022\357\005i\202~\005\\z\301o\012\230Z\014\362\244\324&\243g\351\362\325\375
    30. \213\032\226$\2751\256XR\346k\266\030\234\267\201vUh\004\250\337A\231\223u\247\366/i\022\275\276\350\2
    31. 20\316\306|\203+\010\261;\232\254tp\255\243\261\373Rq;\316w\357\006\207\374U\333\365\365\245hg\031\005
    32. \322\347ea\220\015l\212g\337\264\336b\263\004\311\210.4\340G+\221\274D\035\375\2216\241`\346a0\273wE\2
    33. 12\342y^\202\262|A7\202t\240\333p\345G\373\253\243oCO\011\360\247\211\014\024{\272\271\322<\001\267
    34. \347\240\005\213\0078\036\210\307$\317\322\311\222\035\354\006<\266\264\004\376\251q\256\220(+\030\
    35. 3270\013c\327\272\212%\363\033\252\322\337\354\276\225\232\201\212^\304\210\2269@\3230\370{
  4. 从数据库提取public.key ID:

    1. SELECT pgp_key_id(dearmor('-----BEGIN PGP PUBLIC KEY BLOCK-----
    2. Version: GnuPG v2.0.14 (GNU/Linux)
    3. mQENBFS1Zf0BCADNw8Qvk1V1C36Kfcwd3Kpm/dijPfRyyEwB6PqKyA05jtWiXZTh
    4. 2His1ojSP6LI0cSkIqMU9LAlncecZhRIhBhuVgKlGSgd9texg2nnSL9Admqik/yX
    5. R5syVKG+qcdWuvyZg9oOOmeyjhc3n+kkbRTEMuM3flbMs8shOwzMvstCUVmuHU/V
    6. vG5rJAe8PuYDSJCJ74I6w7SOH3RiRIc7IfL6xYddV42l3ctd44bl8/i71hq2UyN2
    7. /Hbsjii2ymg7ttw3jsWAx2gP9nssDgoy8QDy/o9nNqC8EGlig96ZFnFnE6Pwbhn+
    8. ic8MD0lK5/GAlR6Hc0ZIHf8KEcavruQlikjnABEBAAG0HHRlc3Qga2V5IDx0ZXN0
    9. a2V5QGVtYWlsLmNvbT6JAT4EEwECACgFAlS1Zf0CGwMFCQHhM4AGCwkIBwMCBhUI
    10. AgkKCwQWAgMBAh4BAheAAAoJEAd9cl4gJ8wwbfwH/3VyVsPkQl1owRJNxvXGt1bY
    11. 7BfrvU52yk+PPZYoes9UpdL3CMRk8gAM9bx5Sk08q2UXSZLC6fFOpEW4uWgmGYf8
    12. JRoC3ooezTkmCBW8I1bU0qGetzVxopdXLuPGCE7hVWQe9HcSntiTLxGov1mJAwO7
    13. TAoccXLbyuZh9Rf5vLoQdKzcCyOHh5IqXaQOT100TeFeEpb9TIiwcntg3WCSU5P0
    14. DGoUAOanjDZ3KE8Qp7V74fhG1EZVzHb8FajR62CXSHFKqpBgiNxnTOk45NbXADn4
    15. eTUXPSnwPi46qoAp9UQogsfGyB1XDOTB2UOqhutAMECaM7VtpePv79i0Z/NfnBe5
    16. AQ0EVLVl/QEIANabFdQ+8QMCADOipM1bF/JrQt3zUoc4BTqICaxdyzAfz0tUSf/7
    17. Zro2us99GlARqLWd8EqJcl/xmfcJiZyUam6ZAzzFXCgnH5Y1sdtMTJZdLp5WeOjw
    18. gCWG/ZLu4wzxOFFzDkiPv9RDw6e5MNLtJrSp4hS5o2apKdbO4Ex83O4mJYnav/rE
    19. iDDCWU4T0lhv3hSKCpke6LcwsX+7liozp+aNmP0Ypwfi4hR3UUMP70+V1beFqW2J
    20. bVLz3lLLouHRgpCzla+PzzbEKs16jq77vG9kqZTCIzXoWaLljuitRlfJkO3vQ9hO
    21. v/8yAnkcAmowZrIBlyFg2KBzhunYmN2YvkUAEQEAAYkBJQQYAQIADwUCVLVl/QIb
    22. DAUJAeEzgAAKCRAHfXJeICfMMOHYCACFhInZA9uAM3TC44l+MrgMUJ3rW9izrO48
    23. WrdTsxR8WkSNbIxJoWnYxYuLyPb/shc9k65huw2SSDkj//0fRrI61FPHQNPSvz62
    24. WH+N2lasoUaoJjb2kQGhLOnFbJuevkyBylRz+hI/+8rJKcZOjQkmmK8Hkk8qb5x/
    25. HMUc55H0g2qQAY0BpnJHgOOQ45Q6pk3G2/7Dbek5WJ6K1wUrFy51sNlGWE8pvgEx
    26. /UUZB+dYqCwtvX0nnBu1KNCmk2AkEcFK3YoliCxomdOxhFOv9AKjjojDyC65KJci
    27. Pv2MikPS2fKOAg1R3LpMa8zDEtl4w3vckPQNrQNnYuUtfj6ZoCxv
    28. =XZ8J
    29. -----END PGP PUBLIC KEY BLOCK-----'));
    30. pgp_key_id | 9D4D255F4FD2EFBB

    这会显示用来加密ssn列使用的PGP键ID是9D4D255F4FD2EFBB。只要有新密钥被创建,都推荐执行这一步,然后将该ID保存下来用于跟踪。

    用户可以使用这个键来查看哪一个密钥对被用来加密数据:

    1. SELECT username, pgp_key_id(ssn) As key_used FROM userssn; username | Bob
    2. key_used | 9D4D255F4FD2EFBB
    3. ---------+-----------------
    4. username | Alice
    5. key_used | 9D4D255F4FD2EFBB

    注意: 不同的密钥可能具有相同的ID。这很少见,但是一种普通的事件。客户端应用应该尝试用每一个来解密看看哪一个合适——就像处理ANYKEY一样。请见pgcrypto文档中的pgp_key_id()

  5. 使用私钥解密数据。

    1. SELECT username, pgp_pub_decrypt(ssn, keys.privkey)
    2. AS decrypted_ssn FROM userssn
    3. CROSS JOIN
    4. (SELECT dearmor('-----BEGIN PGP PRIVATE KEY BLOCK-----
    5. Version: GnuPG v2.0.14 (GNU/Linux)
    6. lQOYBFS1Zf0BCADNw8Qvk1V1C36Kfcwd3Kpm/dijPfRyyEwB6PqKyA05jtWiXZTh
    7. 2His1ojSP6LI0cSkIqMU9LAlncecZhRIhBhuVgKlGSgd9texg2nnSL9Admqik/yX
    8. R5syVKG+qcdWuvyZg9oOOmeyjhc3n+kkbRTEMuM3flbMs8shOwzMvstCUVmuHU/V
    9. vG5rJAe8PuYDSJCJ74I6w7SOH3RiRIc7IfL6xYddV42l3ctd44bl8/i71hq2UyN2
    10. /Hbsjii2ymg7ttw3jsWAx2gP9nssDgoy8QDy/o9nNqC8EGlig96ZFnFnE6Pwbhn+
    11. ic8MD0lK5/GAlR6Hc0ZIHf8KEcavruQlikjnABEBAAEAB/wNfjjvP1brRfjjIm/j
    12. XwUNm+sI4v2Ur7qZC94VTukPGf67lvqcYZJuqXxvZrZ8bl6mvl65xEUiZYy7BNA8
    13. fe0PaM4Wy+Xr94Cz2bPbWgawnRNN3GAQy4rlBTrvqQWy+kmpbd87iTjwZidZNNmx
    14. 02iSzraq41Rt0Zx21Jh4rkpF67ftmzOH0vlrS0bWOvHUeMY7tCwmdPe9HbQeDlPr
    15. n9CllUqBn4/acTtCClWAjREZn0zXAsNixtTIPC1V+9nO9YmecMkVwNfIPkIhymAM
    16. OPFnuZ/Dz1rCRHjNHb5j6ZyUM5zDqUVnnezktxqrOENSxm0gfMGcpxHQogUMzb7c
    17. 6UyBBADSCXHPfo/VPVtMm5p1yGrNOR2jR2rUj9+poZzD2gjkt5G/xIKRlkB4uoQl
    18. emu27wr9dVEX7ms0nvDq58iutbQ4d0JIDlcHMeSRQZluErblB75Vj3HtImblPjpn
    19. 4Jx6SWRXPUJPGXGI87u0UoBH0Lwij7M2PW7l1ao+MLEA9jAjQwQA+sr9BKPL4Ya2
    20. r5nE72gsbCCLowkC0rdldf1RGtobwYDMpmYZhOaRKjkOTMG6rCXJxrf6LqiN8w/L
    21. /gNziTmch35MCq/MZzA/bN4VMPyeIlwzxVZkJLsQ7yyqX/A7ac7B7DH0KfXciEXW
    22. MSOAJhMmklW1Q1RRNw3cnYi8w3q7X40EAL/w54FVvvPqp3+sCd86SAAapM4UO2R3
    23. tIsuNVemMWdgNXwvK8AJsz7VreVU5yZ4B8hvCuQj1C7geaN/LXhiT8foRsJC5o71
    24. Bf+iHC/VNEv4k4uDb4lOgnHJYYyifB1wC+nn/EnXCZYQINMia1a4M6Vqc/RIfTH4
    25. nwkZt/89LsAiR/20HHRlc3Qga2V5IDx0ZXN0a2V5QGVtYWlsLmNvbT6JAT4EEwEC
    26. ACgFAlS1Zf0CGwMFCQHhM4AGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEAd9
    27. cl4gJ8wwbfwH/3VyVsPkQl1owRJNxvXGt1bY7BfrvU52yk+PPZYoes9UpdL3CMRk
    28. 8gAM9bx5Sk08q2UXSZLC6fFOpEW4uWgmGYf8JRoC3ooezTkmCBW8I1bU0qGetzVx
    29. opdXLuPGCE7hVWQe9HcSntiTLxGov1mJAwO7TAoccXLbyuZh9Rf5vLoQdKzcCyOH
    30. h5IqXaQOT100TeFeEpb9TIiwcntg3WCSU5P0DGoUAOanjDZ3KE8Qp7V74fhG1EZV
    31. zHb8FajR62CXSHFKqpBgiNxnTOk45NbXADn4eTUXPSnwPi46qoAp9UQogsfGyB1X
    32. DOTB2UOqhutAMECaM7VtpePv79i0Z/NfnBedA5gEVLVl/QEIANabFdQ+8QMCADOi
    33. pM1bF/JrQt3zUoc4BTqICaxdyzAfz0tUSf/7Zro2us99GlARqLWd8EqJcl/xmfcJ
    34. iZyUam6ZAzzFXCgnH5Y1sdtMTJZdLp5WeOjwgCWG/ZLu4wzxOFFzDkiPv9RDw6e5
    35. MNLtJrSp4hS5o2apKdbO4Ex83O4mJYnav/rEiDDCWU4T0lhv3hSKCpke6LcwsX+7
    36. liozp+aNmP0Ypwfi4hR3UUMP70+V1beFqW2JbVLz3lLLouHRgpCzla+PzzbEKs16
    37. jq77vG9kqZTCIzXoWaLljuitRlfJkO3vQ9hOv/8yAnkcAmowZrIBlyFg2KBzhunY
    38. mN2YvkUAEQEAAQAH/A7r4hDrnmzX3QU6FAzePlRB7niJtE2IEN8AufF05Q2PzKU/
    39. c1S72WjtqMAIAgYasDkOhfhcxanTneGuFVYggKT3eSDm1RFKpRjX22m0zKdwy67B
    40. Mu95V2Oklul6OCm8dO6+2fmkGxGqc4ZsKy+jQxtxK3HG9YxMC0dvA2v2C5N4TWi3
    41. Utc7zh//k6IbmaLd7F1d7DXt7Hn2Qsmo8I1rtgPE8grDToomTnRUodToyejEqKyI
    42. ORwsp8n8g2CSFaXSrEyU6HbFYXSxZealhQJGYLFOZdR0MzVtZQCn/7n+IHjupndC
    43. Nd2a8DVx3yQS3dAmvLzhFacZdjXi31wvj0moFOkEAOCz1E63SKNNksniQ11lRMJp
    44. gaov6Ux/zGLMstwTzNouI+Kr8/db0GlSAy1Z3UoAB4tFQXEApoX9A4AJ2KqQjqOX
    45. cZVULenfDZaxrbb9Lid7ZnTDXKVyGTWDF7ZHavHJ4981mCW17lU11zHBB9xMlx6p
    46. dhFvb0gdy0jSLaFMFr/JBAD0fz3RrhP7e6Xll2zdBqGthjC5S/IoKwwBgw6ri2yx
    47. LoxqBr2pl9PotJJ/JUMPhD/LxuTcOZtYjy8PKgm5jhnBDq3Ss0kNKAY1f5EkZG9a
    48. 6I4iAX/NekqSyF+OgBfC9aCgS5RG8hYoOCbp8na5R3bgiuS8IzmVmm5OhZ4MDEwg
    49. nQP7BzmR0p5BahpZ8r3Ada7FcK+0ZLLRdLmOYF/yUrZ53SoYCZRzU/GmtQ7LkXBh
    50. Gjqied9Bs1MHdNUolq7GaexcjZmOWHEf6w9+9M4+vxtQq1nkIWqtaphewEmd5/nf
    51. EP3sIY0EAE3mmiLmHLqBju+UJKMNwFNeyMTqgcg50ISH8J9FRIkBJQQYAQIADwUC
    52. VLVl/QIbDAUJAeEzgAAKCRAHfXJeICfMMOHYCACFhInZA9uAM3TC44l+MrgMUJ3r
    53. W9izrO48WrdTsxR8WkSNbIxJoWnYxYuLyPb/shc9k65huw2SSDkj//0fRrI61FPH
    54. QNPSvz62WH+N2lasoUaoJjb2kQGhLOnFbJuevkyBylRz+hI/+8rJKcZOjQkmmK8H
    55. kk8qb5x/HMUc55H0g2qQAY0BpnJHgOOQ45Q6pk3G2/7Dbek5WJ6K1wUrFy51sNlG
    56. WE8pvgEx/UUZB+dYqCwtvX0nnBu1KNCmk2AkEcFK3YoliCxomdOxhFOv9AKjjojD
    57. yC65KJciPv2MikPS2fKOAg1R3LpMa8zDEtl4w3vckPQNrQNnYuUtfj6ZoCxv
    58. =fa+6
    59. -----END PGP PRIVATE KEY BLOCK-----') AS privkey) AS keys;
    60. username | decrypted_ssn
    61. ----------+---------------
    62. Alice | 123-45-6788
    63. Bob | 123-45-6799
    64. (2 rows)

    如果用户使用口令创建一个密钥,用户可能必须在这里输入口令。不过对于这个例子的目的,口令为空。

加密gpfdist连接

gpfdists协议是gpfdist协议的一个安全版本,它能安全地标识文件服务器和Greenplum数据库并且加密其间的通信。使用gpfdists可以防止窃听和中间人攻击。

gpfdists协议利用下列值得注意的特性实现客户端/服务器的SSL安全性:

  • 要求客户端证书。
  • 不支持多语言证书。
  • 不支持证书撤销列表(CRL)。
  • TLSv1协议被用于TLS_RSA_WITH_AES_128_CBC_SHA加密算法。这些SSL参数不能被更改。
  • 不支持SSL再协商。
  • SSL忽略主机失配参数被设置为false。
  • gpfdist服务器(server.key)或Greenplum数据库(client.key)不支持含有口令的私钥。
  • 为使用的操作系统颁发合适的证书是用户的责任。通常,支持将证书转换成所要求的格式,例如可使用https://www.sslshopper.com/ssl-converter.html的SSL转换器。

用--ssl选项启动的gpfdist服务器只能用gpfdists协议通信。没有用--ssl选项启动的gpfdist服务器只能用gpfdist协议通信。更多有关gpfdist的细节请参考Greenplum数据库管理员指南

有两种方式启用gpfdists协议:

  • 用--ssl选项运行gpfdist,然后在CREATE EXTERNAL TABLE语句的LOCATION子句中使用gpfdists协议。
  • 在YAML控制文件中将SSL选项设置为真,然后用它来运行gpload。运行的gpload会用--ssl选项启动gpfdist服务器,然后使用gpfdists协议。

在使用gpfdists时,下列客户端证书必须位于每个Segment的$PGDATA/gpfdists目录中:

  • 客户端证书文件,client.crt
  • 客户端私钥文件,client.key
  • 受信证书发布机构,root.crt

重要: 不要用口令保护私钥。服务器不会为私钥提示要求口令,并且数据装载会在要求口令时失败报错。

在使用带SSL的gpload时,用户要在YAML控制文件中指定服务器证书的位置。在使用带SSL的gpfdist时,用户用—ssl选项指定服务器证书的位置。

下面的例子展示了如何安全地装载数据到外部表中。这个例子从所有带txt扩展名的文件使用gpfdists协议创建一个可读外部表ext_expenses。这些文件被格式化为用一个竖线(|)作为列定界符,并且用空格表示空。

  1. 在Segment主机上用--ssl选项运行gpfdist。
  2. 登入数据库并执行下列命令:

    1. =# CREATE EXTERNAL TABLE ext_expenses
    2. ( name text, date date, amount float4, category text, desc1 text )
    3. LOCATION ('gpfdists://etlhost-1:8081/*.txt', 'gpfdists://etlhost-2:8082/*.txt')
    4. FORMAT 'TEXT' ( DELIMITER '|' NULL ' ') ;

上级主题: 最佳实践

1 SHA2算法在版本0.9.8时被加入OpenSSL。对于较老的版本,pgcrypto将使用内建代码。

2 OpenSSL支持的任何摘要算法都会被自动地取用。而加密算法则不能这样,它们需要被明确地支持。

3 AES从0.9.7开始被包括在OpenSSL中。对于较老的版本,pgcrypto将使用内建代码。