代码之家  ›  专栏  ›  技术社区  ›  InverseFalcon

密钥库使用的基本问题

  •  4
  • InverseFalcon  · 技术社区  · 15 年前

    我有一个生成秘密密钥的应用程序,每个客户端一个。这些需要保存在我们的数据库中。我真的不熟悉常见的安全模式或实现,我正在寻求建议。

    KeyStore类似乎被广泛使用,尤其是用来保护秘密密钥。然而,我很少提到在数据库中使用KeyStore,我试图弄清楚这是因为它的基本用法(因此没有提及),还是因为这是一种不好的或冗余的方法,我真的应该使用一种不同的技术。

    基本的设计是每个用户都有自己的密钥库,通过转换成字节(我认为使用load()和store())将密钥库保存/加载到数据库或从数据库加载密钥库。

    到目前为止这个设计有什么问题吗?我还想知道应该如何处理密钥库的密码。我们正在考虑对所有密钥库只使用一个密码,但是如果没有密钥库,我们如何安全地存储这个密码呢?

    2 回复  |  直到 15 年前
        1
  •  5
  •   Vineet Reynolds    15 年前

    在现实世界中,密钥是 安全存放 (强调我的)在 HSM 如果他们打算安全地储存,一段很长的时间(从几个小时到几年不等)。这就是 PKCS#11

    密钥也可以安全地存储在智能卡和USB令牌等其他设备中,但这是为了在大众中分发密钥,而不是用于后端系统的密钥存储。

    然而,并不是每个人都能得到HSMs的预算,而且还使用了许多其他不太安全(显然更便宜)的替代品。一些系统(我将以Glassfish应用服务器为例)存储主密码,用于保护其他密码。这同样适用于密钥-将有一个主密钥用于保护其他密钥(在某种程度上,这类似于HSMs内部的工作方式)。当然,你还得把主钥匙锁好。在某些环境中,这很容易,因为您可以将密钥放在仅限系统管理员和应用程序使用的文件中,而不允许其他人使用。

    :所有这些都不应视为盲目接受的建议:-)。如果你的钥匙需要不惜一切代价得到保护,那就投资一个高速移动设备。

        2
  •  4
  •   Fico    12 年前

    所以您使用的是java和keystores。

    1) 你需要一些建议

    2) 你想知道如何把这些东西存储到数据库吗

    回答问题1: 所以在使用java时,需要使用SSL。Java已经实现了通过https进行通信的类,它将为您执行SSL握手和所有操作!唯一需要做的就是为这个实现提供java.security.KeyStore。

    你如何制作你的私钥和证书,我将不在这里讨论。我想你已经在那里了(如果没有,你会发现的)。但是密钥库是受密码保护的。所以一般来说,如果没有人能入侵你的数据库,它们是安全的。如果将打开密钥库的密码存储在同一个表中,请注意sql注入! 但我们假设这是安全的。。密钥库使您能够使用将处理SSL握手的现有实现。所以基本上使用keystores并不是一件坏事。注意:顺便说一句,只有在需要相互身份验证(也就是说,您还需要标识自己)时,才会使用PKCS12密钥库。

    是的,您可以在数据库中存储密钥库,这有点棘手。因为密钥库只允许它们使用存储和加载方法。但你可以这样做:

    @Entity
    public class MyKeyStoreClass {
    private Long id;
    @Transient
    private KeyStore keystore;
    private String passwordForKeyStore;
    private Byte[] keyStoreAsBytes;
    
    @PreUpdate
    @PrePersist
    public void concertKeyStoreToBytes() {
       ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            keystore.store(byteArrayOutputStream,
                    passwordForKeyStore.toCharArray());
       keyStoreAsBytes = byteArrayOutputStream.toByteArray();
    }
    
    @PostLoad
    public void getKeyStore() {
       if (keystore == null && keyStoreAsBytes != null) {
          keyStore = KeyStore.getInstance(getKeystoreType().getType());
          keyStore.load(new ByteArrayInputStream(keystoreAsBytes), passwordForKeyStore.toCharArray()); 
       }    
    }
    

    上面的代码可能不是100%正确,因为我在这里写的(没有编辑器)。但这通常是你能做到的,我以前做过,而且效果很好;)