Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中RSA私钥的加密_Java_Encryption_Cryptography_Rsa_Private Key - Fatal编程技术网

Java中RSA私钥的加密

Java中RSA私钥的加密,java,encryption,cryptography,rsa,private-key,Java,Encryption,Cryptography,Rsa,Private Key,我正在尝试使用RSA私钥加密某些内容 我遵循这个例子: 但将其转换为使用私钥而不是公钥。按照这个例子,我认为我需要做的是: 以DER格式私钥读取 生成PCKS8EncodedKeySpec 从KeyFactory调用generatePrivate()以获取私钥对象 将该私钥对象与Cipher对象一起使用以进行加密 因此,步骤如下: 密钥是通过以下方式从openssl生成的: openssl genrsa-aes256-out private.pem 2048 然后使用以下命令转换为DER格

我正在尝试使用RSA私钥加密某些内容

我遵循这个例子:

但将其转换为使用私钥而不是公钥。按照这个例子,我认为我需要做的是:

以DER格式私钥读取
  • 生成PCKS8EncodedKeySpec
  • 从KeyFactory调用generatePrivate()以获取私钥对象
  • 将该私钥对象与Cipher对象一起使用以进行加密
  • 因此,步骤如下:

    密钥是通过以下方式从openssl生成的:

    openssl genrsa-aes256-out private.pem 2048

    然后使用以下命令转换为DER格式:

    openssl rsa-in private.pem-outform DER-out private.DER

    我使用以下命令生成PKCS8EncodedKeySpec:

    byte[] encodedKey = new byte[(int)inputKeyFile.length()];
    
    try {
        new FileInputStream(inputKeyFile).read(encodedKey);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey);
    return privateKeySpec;
    
    然后使用以下命令生成私钥对象:

    PrivateKey pk = null;
    
    try {
        KeyFactory kf = KeyFactory.getInstance(RSA_METHOD);
        pk = kf.generatePrivate(privateKeySpec);
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeySpecException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return pk;
    
    然而,在呼吁:

    pk = kf.generatePrivate(privateKeySpec);
    
    我得到:

    java.security.spec.InvalidKeySpecException: Unknown key spec.
    at com.sun.net.ssl.internal.ssl.JS_KeyFactory.engineGeneratePrivate(DashoA12275)
    at com.sun.net.ssl.internal.ssl.JSA_RSAKeyFactory.engineGeneratePrivate(DashoA12275)
    at java.security.KeyFactory.generatePrivate(KeyFactory.java:237)
    
    问题:

    • 一般方法正确吗
    • PCKS8EncodedKeySpec是要使用的正确密钥规范吗
    • 关于无效密钥规范错误有什么想法吗

    首先,我不明白为什么您计划使用
    密码
    用私钥加密,而不是用
    签名
    签名。我不确定所有RSA
    Cipher
    提供程序是否会使用正确的块类型进行设置,但值得一试

    尽管如此,我认为您正在尝试加载一个非标准的OpenSSL格式密钥。使用rsa将其转换为DER本质上只是一个base-64解码;密钥的结构不是PKCS#8

    相反,在
    genrsa
    之后,使用
    openssl pkcs8
    命令将生成的密钥转换为未加密的PKCS#8,DER格式:

    openssl pkcs8 -topk8 -nocrypt -in private.pem -outform der -out private.der
    

    这将生成一个未加密的私钥,该私钥可以使用无法使用私钥加密的PKCS8EncodedKeySpec加载。如果JCE允许你这么做,那只是偶然的

    你需要使用签名。下面是实现这一点的代码片段

    signer = Signature.getInstance("SHA1withRSA");
    signer.initSign(privateKey); // PKCS#8 is preferred
    signer.update(dataToSign);
    byte[] signature = signer.sign();
    

    允许使用私钥进行加密并非偶然。如果要将签名分解为单独的散列和加密,则必须使用私钥进行加密。 假设我有一个需要签名的文档,并且我的密钥驻留在网络HSM上。现在,要么我将整个文档流式传输到HSM进行签名,要么我可以创建一个本地哈希并将其流式传输到HSM进行单独加密。
    我的选择将取决于本地哈希计算是否为我提供了更好的性能,即具有网络延迟的viz委托哈希计算。

    这个问题很老了,但我最近偶然发现了这个问题(我正在实现一些协议的要求,这些协议要求使用私钥进行加密)。我将引用以下文章:

    我最近偶然发现了同样的问题,在咨询“开发”(不管是谁)裁定私钥不能用于加密后,提交了PMR 22265、49R和IBM支持。无论我多么努力地与他们争论私钥不应用于数据保护,这只是加密背后的一个目的,使用私钥进行加密以实现不可否认性是完全正确的,他们的信念是不可动摇的。你必须爱那些坚持2x2=5的人

    我是如何解决这个问题的:本质上,我用私钥的加密材料创建了一个公钥对象。如果要避免“公钥不能用于解密”异常,则需要执行相反的操作,使用公钥的加密材料创建私钥对象,以使用公钥进行解密

    试试这个:

    java.security.Security.addProvider(
                         new org.bouncycastle.jce.provider.BouncyCastleProvider()
                );
    

    老实说,我不知道签名。为了确保我理解它的用法,我将初始化signature对象,用我想要签名的字节调用update,然后调用sign?然后我可以把sign返回的字节存储为我的数字签名?您好。有人最终解决了这个问题吗?我有一个私钥,无法加载到java中继续签名阶段。我的私钥是RSA,PKCS#8 DER,它有密码。如何将其加载到java中?我的例子中的异常是
    java.security.spec.InvalidKeySpecException:java.security.InvalidKeyException:IOException:DER input,Integer tag error
    @BRabbit27要直接加载私钥,它必须是未加密的。使用上面显示的
    opensslpkcs8
    命令,添加选项
    -inform der
    ;它将提示您输入密码。如果您希望对私钥进行加密(我强烈建议),则需要将其添加到密钥存储(如PKCS#12文件),并通过Java中的
    KeyStore
    API对其进行访问。@erickson我尝试了该命令,但在解密密钥时显示错误(我使用的是WinOpenSSL)。我使用的命令是
    opensslpkcs8-topk8-nocrypt-in myKey.key-inform der-outform der-out myNoCryptKey.key
    更新-nocrypt选项应该做什么?我想我做了一个类似这样的解决方法
    openssl pkcs8-inform DER-in-myKey.key-outform PEM-out myKeyInPEM.key
    它向我询问密码,然后
    openssl pkcs8-topk8-nocrypt-in-myKeyInPEM-outform DER-out myKeyInDERNoCrypted.key
    它没有询问我的密码,但结果文件似乎是相同的myKey.key
    s/public/private/
    在您的第一行中。我浏览了这篇文章并用Java生成了它们:如果您将私钥指数视为公共指数并分发它,这是非常危险的,因为给定私钥(您称之为“公钥”),很容易派生出实际的公钥(您现在称之为“私钥”)。不要不小心将“公钥”公开,否则您的系统将受到危害。这可能很简单,只需猜测“私钥”的指数是65537。我搜索了这么久。我非常感谢这个答案。“私钥和公钥”这个名称在这个用例中是完全错误的
    java.security.Security.addProvider(
                         new org.bouncycastle.jce.provider.BouncyCastleProvider()
                );