如何导出keystore中的私钥

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何导出keystore中的私钥相关的知识,希望对你有一定的参考价值。

一般情况下,你通过keytool生成的密钥对中的私钥是无法导出来的,
但是通过自己的Java代码可以做到这点。

Java代码

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import sun.misc.*;
public class ExportPrivateKey
private File keystoreFile;
private String keyStoreType;
private char[] password;
private String alias;
private File exportedFile;
public static KeyPair getPrivateKey(KeyStore keystore, String alias, char[] password)
try
Key key=keystore.getKey(alias,password);
if(key instanceof PrivateKey)
Certificate cert=keystore.getCertificate(alias);
PublicKey publicKey=cert.getPublicKey();
return new KeyPair(publicKey,(PrivateKey)key);

catch (UnrecoverableKeyException e)
catch (NoSuchAlgorithmException e)
catch (KeyStoreException e)

return null;

public void export() throws Exception
KeyStore keystore=KeyStore.getInstance(keyStoreType);
BASE64Encoder encoder=new BASE64Encoder();
keystore.load(new FileInputStream(keystoreFile),password);
KeyPair keyPair=getPrivateKey(keystore,alias,password);
PrivateKey privateKey=keyPair.getPrivate();
String encoded=encoder.encode(privateKey.getEncoded());
FileWriter fw=new FileWriter(exportedFile);
fw.write("—–BEGIN PRIVATE KEY—–\n");
fw.write(encoded);
fw.write("\n");
fw.write("—–END PRIVATE KEY—–");
fw.close();

public static void main(String args[]) throws Exception
ExportPrivateKey export=new ExportPrivateKey();
export.keystoreFile=new File("/Users/Luke/Workspace/StringTest/src/com/lukejin/stringtest/keystore.jks");
export.keyStoreType="JKS";
export.password="changeit".toCharArray();
export.alias="tom_server";
export.exportedFile=new File("luke");
export.export();



出自:http://lukejin.iteye.com/blog/586073
参考技术A 使用java程序语言导出私钥的方式,下载kestore-export.工具:
Java Runtime的目录,指包含Java.exe和keytool.exe的目录,如:
c:\progra~1\Java\jre1.5.0_06\bin
例如:
Cmd代码
JKS2PFX server.jks 123456 tomcat exportfile c:\progra~1\Java\jre1.5.0_06\bin

Export-PfxCertificate:无法导出不可导出的私钥

【中文标题】Export-PfxCertificate:无法导出不可导出的私钥【英文标题】:Export-PfxCertificate : Cannot export non-exportable private key 【发布时间】:2018-02-21 20:56:40 【问题描述】:

我正在尝试导出我的自签名证书,以便将其导入我的开发环境中的其他服务器(将使用“真实”证书进行生产),但它会引发以下错误:

Export-PfxCertificate : 无法导出不可导出的私钥

要求是我需要导出证书并“允许导出私钥”,但很好奇我缺少什么。我的PowerShell如下:

$pwd = ConvertTo-SecureString -String ‘1234’ -Force -AsPlainText
$path = 'cert:\localMachine\my\' + '1E7439053EE57AEE6EA0E1F3CDF5DB4234B6731E' 
Export-PfxCertificate -cert $path -FilePath c:\Certificates\cert.pfx -Password $pwd

【问题讨论】:

查看这个旧的 SO 帖子:***.com/questions/3914882/… 不确定是否有一种开箱即用的方式可以使用 powershell 完成,但可能与 mimikatz 或 jailbrea 结合使用,您可以在循环中批量执行此操作跨度> 我有一个脚本用于批量导出证书...不确定是否有帮助但值得一试github.com/crshnbrn66/certlib/blob/master/certLib.ps1 【参考方案1】:

问题不在于 powershell 代码。问题出在证书上。

首次导入或创建证书时,必须将私钥标记为可导出才能导出私钥。

您收到的错误消息表明您尝试使用的证书上的私钥不可导出。

Example Issue

【讨论】:

示例链接已损坏。【参考方案2】:

也许为时已晚,但您是否尝试过以管理员身份运行 PowerShell 脚本? (如果您可以从 mmc 控制台导出私钥,Export-PfxCertificate 也会将其导出。)

【讨论】:

您无需成为管理员即可导出您的密钥,但您需要有可用的密钥才能导出它们。 如果我以用户身份启动脚本,我只能从 \LocalMachine\My 导出公钥。此外,Export-PfxCertificate 返回错误“无法导出不可导出的私钥”。但是,如果我从提升的命令提示符启动 PS,则不会出现错误,并且 PFX 文件包含 pub 和 priv 密钥。 如果你可以在certlm.msc中手动导出证书,因为它被标记为可导出,但是你在PowerShell中仍然出现这个错误,那么这就是解决方案。例如,如果您未提升权限,则无法导出 IIS 证书。【参考方案3】:

我知道这是一个较老的问题,但我想发布我的解决方案,因为我遇到了同样的问题。 在尝试导出我的 PFX 文件时,我也遇到了可怕的 Export-PfxCertificate : Cannot export non-exportable private key 错误。 在我的 Windows 机器上加载我的代码签名证书后,问题就开始了。 当我去导出它时,导出到 PFX 选项是灰色的,没有进一步的解释。然后我按照此处列出的许多说明进行操作,包括 Powershell Export-PfxCertificate。这些都不起作用。 我终于回到了我的证书提供商 GoDaddy,他们告诉我,在我的原始证书签名请求 (CSR) 中,我没有选中 Make Private Key Exportable 框。 GoDaddy 慷慨且免费地允许我提交新的 CSR(选中该选项)以“重新加密”我现有的证书。几个小时后,我的新证书就颁发了。我将它安装在我的机器上,并且能够直接从 Windows MMC 导出(无需 PowerShell。) 我已经包含了创建 CSR 时必须选中的框的屏幕截图(在不同平台上可能看起来不同。)

【讨论】:

【参考方案4】:

我快速搜索了一下,你可以使用certutil 或者更好的可能是http://community.idera.com/powershell/powertips/b/tips/posts/exporting-certificate-with-private-key 的解决方案。

该帖子中的相关代码已粘贴在下面。 100% 归属于该页面的作者。

dir cert:\currentuser\my | 
Where-Object  $_.hasPrivateKey  | 
Foreach-Object  [system.IO.file]::WriteAllBytes(
"$home\$($_.thumbprint).pfx", 
($_.Export('PFX', 'secret')) ) 

【讨论】:

【参考方案5】:

使用Import-PfxCertificate with parameter -Exportable

Get-ChildItem -路径 c:\mypfx\my.pfx | Import-PfxCertificate -CertStoreLocation Cert:\CurrentUser\My -Exportable

【讨论】:

【参考方案6】:

在下面查看我的代码。

#Ask for the Name 
$name = Read-Host "Certificate Name "

# Check if the Path exists
$Path = "D:\Provisioning\certmgmt\$name.txt"
$TestPath = Test-Path $Path
if ($TestPath -ne "true")

    Write-Host "The Path $Path do not exist" -ForegroundColor Red
    Pause
    exit


# Import the certificate
$result = Import-Certificate -FilePath $Path -CertStoreLocation "Cert:\LocalMachine\My" 

# Get the serialnumber of the certificate
$Thumbprint = $result.Thumbprint

# Set the FriendlyName
(Get-ChildItem -Path Cert:\LocalMachine\My\$Thumbprint).FriendlyName = $name  

# Export the Certificate
$answer = Read-Host "Export Certificate? (Y/N)"

if ($answer -eq "N" -or $answer -eq "n")

    exit



    try
    
       $mypwd = ConvertTo-SecureString -String "password" -Force -AsPlainText
       Get-ChildItem -Path cert:\localMachine\my\$Thumbprint | Export-PfxCertificate -FilePath C:\$name.pfx -Password $mypwd
    
    catch
    
      Write-Host $Error -ForegroundColor Red
      pause
      exit
    

    Write-Host "Export the Certifikate was successful" -ForegroundColor Green

【讨论】:

以上是关于如何导出keystore中的私钥的主要内容,如果未能解决你的问题,请参考以下文章

以太坊钱包开发系列2 - 账号Keystore文件导入导出

[转]简单科普私钥地址助记词Keystore的区别

openssl 使用说明

关于钱包的一些概念

Java安全(JCA/JSSE):数字证书

Android java更新Android KeyStore中的证书和私钥