【问题标题】:Self -Signed certificate vs CA自签名证书与 CA
【发布时间】:2020-07-30 15:25:06
【问题描述】:

我正在为通过 RSA 和 AES 组合的文件加密制定解决方案。这里主要使用 RSA 进行握手,加密对称密钥,并在接收端通过密钥对解密。

我已将 Java 密钥库用于私钥,将自签名证书用于公钥。两者都创建如下:

钥匙店

keytool -genkey -keyalg RSA -alias BANK -keystore receiverKeystore.jks -validity 360 -keysize 2048

证书导出

keytool -export -alias BANK -keystore receiverKeystore.jks -rfc -file bankCert.cer

类似地,两者都在 Java 中使用如下:

私钥

private void setKeys() {

        KeyStore senderKeyStore = null;
        String keyStorePassword = "fms123";

        try {

            senderKeyStore = KeyStore.getInstance( "JKS" );  
            FileInputStream is = new FileInputStream( keystorePath );
            senderKeyStore.load( is, keyStorePassword.toCharArray() );  

            senderPrivateKey = ( PrivateKey ) senderKeyStore.getKey( KEYSTORE_ALIAS, keyStorePassword.toCharArray() );

            receiverPublicKey = loadReceiverPublicKeyFromCertificate();
        }
        catch ( Exception e ) {
            System.out.println( " Exception in setting keys from key store = " + e );
        }

    } 

公钥

private PublicKey loadReceiverPublicKeyFromCertificate () {

        PublicKey publicKey = null; 

        try {

            FileInputStream fin = new FileInputStream( certificateFilePath );
            CertificateFactory factory = CertificateFactory.getInstance( "X.509" );
            X509Certificate certificate = ( X509Certificate ) factory.generateCertificate( fin );
            publicKey = certificate.getPublicKey();
        }
        catch ( Exception e ) {
            System.out.println( " Exception in loading receiver certificate = " + e );
        }

        return publicKey;
    }

我现在有以下问题:

  1. 这样做的方法是否正确?
  2. 如果我在这里使用受信任的证书,如何从中获取公钥?会以同样的方式获取吗?和私钥?我会使用相同的方法或证书中的内容吗?

  3. 如何将我的证书分发给接收者?为此,安全通信应该是什么?

我是加密新手,很高兴得到一些建议。

【问题讨论】:

  • 1.是的,但是您可以从密钥库中获取公钥,如 Javadoc 中所示:只需从 PrivateKeyEntry 获取证书并从中获取公钥。 2. 同样的方式。 3. 你需要一个离线机制。你不能通过它打算保护的机制来运输它。
  • 感谢您的回复,请问我应该使用 CA 还是自签名?
  • 如果您对 (3) 有一个好的解决方案,您可以使用自签名,但 CA 证书消除了这种需要。
  • 好的,可以说,我要使用自签名证书;那么我的代码是否可以满足解决方案,即获取密钥?
  • 您遗漏了关键细节。你从来没有在你的问题中提到过 ssl,它只是作为你的标签之一出现。您将从混合加密的摘要开始。这是否意味着您没有使用 SSL,而是编写自己的自定义安全协议?另一个关键考虑因素是客户的性质。客户端软件只是标准的网络浏览器吗?如果是这样,那么您应该使用商业 ca。另一方面,如果您的客户是您编写的应用程序,那么使用商业 ca 的几乎所有好处都将消失,而自签名证书可能是可行的方法。

标签: java ssl encryption


【解决方案1】:

您的握手称为密钥建立。握手用于(在线)传输模式,我不认为你正在开发它。我会改用 PKCS#12 密钥库,JKS 有点过时了。使用char[] 作为密码的整个想法是您可以在使用后直接删除其内容,因此使用String 作为输入不是一个好主意。字符串通常是interned,并且在 Java 中总是不可变,所以如果没有涉及本机代码的丑陋 hack,就无法销毁它们。

受信任的证书与不受信任的证书没有区别。是的,您可以从中检索公钥。私钥通常与通向私钥所属叶用户证书的证书链一起存储。但是,私钥不是证书的一部分,因此您无法从中检索私钥。不过没关系,私钥应该在需要它们的位置建立;除了用于备份目的之外,无需传输它们。

如何将证书发送给接收者取决于您。棘手的部分是让接收者信任证书。使用预先建立的密钥(例如受信任的 PGP 密钥)是有效的。如果你没有这样的钥匙,那么你就有麻烦了。您可以做的是使用其他方法来建立信任。让对方给你打电话,然后验证证书指纹(基本上只是证书上的哈希)是否正确可能是最简单的方法之一。如果您的用户离您不太远,那么亲自带过来当然也是一种选择。

但是,您不能凭空创建安全通道。如果你不能信任对方,那么建立完全信任显然是不可能的。

【讨论】:

  • 我正在使用来自密钥库的密钥和自签名证书。这样好吗?
  • 或者我将转向 OpenPGP?
  • 是的,这对于小规模操作来说很好。您必须依靠受信任的第三方来处理其他任何事情。我会根据信任模型在 CMS 和 OpenPGP 之间进行选择,但在您的情况下,CMS 似乎是更合乎逻辑的选择。
  • 你能解释一下CMS吗?
  • 不,这要求有点高,请阅读维基百科页面或其他内容。如果您有任何疑问,总有 stackexchange 的加密和 IT 安全站点。请注意,在 cmets 中提出其他问题并不被认为是一种好的做法,尤其是在原始问题已得到充分回答的情况下。
猜你喜欢
  • 1970-01-01
  • 2012-07-20
  • 2012-07-19
  • 1970-01-01
  • 2016-07-08
  • 2016-01-22
  • 2018-12-28
  • 2021-01-09
  • 1970-01-01
相关资源
最近更新 更多