我有私钥存储在PKCS8 DER格式的文件中,并受密码保护.最简单的阅读方式是什么?
这是我用来加载未加密的代码:
InputStream in = new FileInputStream(privateKeyFilename);
byte[] privateKeydata = new byte[in.available()];
in.read(privateKeydata);
in.close();
KeyFactory privateKeyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(privateKeydata);
PrivateKey privateKey = privateKeyFactory.generatePrivate(encodedKeySpec);
Run Code Online (Sandbox Code Playgroud)
它适用于具有相同规范的未加密密钥.顺便说一下,我正在使用BouncyCastle.
我可以使用以下openssl命令查看此私钥
openssl pkcs8 -in ./privatekey.key -inform DER -passin pass:thisismypass
Run Code Online (Sandbox Code Playgroud)
请帮忙!!!
我已经在我自己对这个主题的回答中发布了一些解决方案.但是如果没有额外的库,只有BouncyCastle,任何人都可以提供帮助,我仍然无法回答问题.
我正在弄乱C#Bouncy Castle API以找到如何进行PBKDF2密钥派生.
我现在真的很无能为力.
我尝试通过Pkcs5S2ParametersGenerator.cs和PBKDF2Params.cs文件阅读,但我真的无法弄清楚如何做到这一点.
根据我迄今为止所做的研究,PBKDF2需要一个字符串(或char []),它是密码,盐和迭代计数.
到目前为止,迄今为止最有前途和最明显的是PBKDF2Params和Pkcs5S2ParametersGenerator.
这些似乎都不接受字符串或char [].
有没有人用C#做过这个或者对此有任何线索?或者也许有人在Java中实现了BouncyCastle并可以提供帮助?
Thanx提前很多:)
更新:我在Bouncy Castle找到了如何做到这一点.看下面的答案:)
我按照这个指示添加bouncycastle:http: //www.bouncycastle.org/wiki/display/JA1/Provider+Installation 但我还有一个问题.有时,当我重新部署我的应用程序时,找不到此提供程序,因此我的应用程序抛出异常.每100次重新部署(可能更少)只出现一个问题.当我重新启动我的服务器 - weblogic然后它再次开始工作.我将非常感谢有关此问题发生的任何建议
编辑:
我在上面的链接中使用这两种方法,因为当我只使用其中一种然后它不起作用我添加到java.security这个提示,然后在我的类我注册了这个提示:
static {
Security.addProvider(new BouncyCastleProvider());
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试与证书设置为2013年4月到期的服务器建立HTTPS连接,并使用GlobalSign作为根证书.
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
// urlConnection.setSSLSocketFactory(sslSocketFactory);
urlConnection.setDoOutput(true);
urlConnection.setChunkedStreamingMode(0);
// Send the POST data
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
out.write(postParamString.toString().getBytes("UTF8"));
// Read the reply
InputStream in = urlConnection.getInputStream();
Run Code Online (Sandbox Code Playgroud)
就目前而言,这会javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate signature.在getOutputStream()被召唤时抛出.
此相同的站点和证书在HTC Web浏览器和桌面浏览器中有效.当我使用相同的代码访问Google时,它可以工作(但随后会抱怨404错误).StackOverflow上的各种帖子暗示它应该"正常工作"而其他人说要设置自己的密钥库(或禁用所有HTTPS验证!)我假设行为的差异归结为使用中的不同根密钥库(任何人都可以澄清这一点?).
我现在尝试使用充气城堡创建一个密钥库,但我无法将其加载到我的设备上.
从Firefox导出证书后,我使用以下方法创建密钥库:
keytool.exe -import -alias onlinescoutmanager -file www.onlinescoutmanager.co.uk.crt -storetype BKS -keystore res\raw\keystore
Run Code Online (Sandbox Code Playgroud)
然后使用以下命令加载并在应用程序中使用:
InputStream stream = context.getResources().openRawResource(R.raw.keystore);
// BKS seems to be the default but we want to be explicit
KeyStore ks = KeyStore.getInstance("BKS"); …Run Code Online (Sandbox Code Playgroud) 在我的构建过程中,我想要包含符合RFC-3161标准的TSA的时间戳.在运行时,代码将验证此时间戳,最好不需要第三方库的帮助.(这是一个.NET应用程序,所以我可以随时使用标准的哈希和非对称加密功能.)
RFC 3161依赖于ASN.1和X.690以及诸如此类的东西,实现起来并不简单,所以至少现在,我正在使用Bouncy Castle来生成TimeStampReq(请求)并解析TimeStampResp(响应).我只是无法弄清楚如何验证响应.
到目前为止,我已经弄清楚如何提取签名本身,公共证书,创建时间戳的时间,以及我发送的消息imprint摘要和nonce(用于构建时验证).我无法弄清楚的是如何将这些数据放在一起以生成散列和签名的数据.
这是我正在做什么以及我想做什么的粗略概念.这是测试代码,所以我采取了一些快捷方式.一旦我得到了有效的东西,我将不得不清理一些事情并以正确的方式完成它们.
// a lot of fully-qualified type names here to make sure it's clear what I'm using
static void WriteTimestampToBuild(){
var dataToTimestamp = Encoding.UTF8.GetBytes("The rain in Spain falls mainly on the plain");
var hashToTimestamp = new System.Security.Cryptography.SHA1Cng().ComputeHash(dataToTimestamp);
var nonce = GetRandomNonce();
var tsr = GetTimestamp(hashToTimestamp, nonce, "http://some.rfc3161-compliant.server");
var tst = tsr.TimeStampToken;
var tsi = tst.TimeStampInfo;
ValidateNonceAndHash(tsi, hashToTimestamp, nonce);
var cms = tst.ToCmsSignedData();
var signer =
cms.GetSignerInfos().GetSigners()
.Cast<Org.BouncyCastle.Cms.SignerInformation>().First();
// TODO: handle multiple signers?
var signature …Run Code Online (Sandbox Code Playgroud) trust bouncycastle digital-signature trusted-timestamp rfc3161
我们还有一个Android项目,我们使用MockitoTestRunner和RobolectricTestRunner进行不同类型的测试.
我编写了一组与SSL有关的单元测试,因此加载了证书/密钥库/信任库等.为此,我使用MockitoJUnitRunner并以编程方式添加了Bouncycastle提供程序:
Security.insertProviderAt(new BouncyCastleProvider(), 1);
Run Code Online (Sandbox Code Playgroud)
现在,这些测试在自己运行时运行得非常好 - 例如,当我直接从测试类中运行单个方法,或者从Project树菜单中运行这些类时,它们工作得很好.
但是,当我运行沿着所述侧测试ANY它使用测试RobolectricTestRunner(例如,如果我只是犯前一起运行在我的项目的所有测试),我得到以下异常:
java.io.IOException: error constructing MAC:
java.lang.SecurityException: JCE cannot authenticate the provider BC
Run Code Online (Sandbox Code Playgroud)
我很困惑.一个测试类中使用的testrunner将如何影响其他类的运行,特别是如果我们使用不同的测试运行器?
附加信息:
insertProviderAt(...)调用本身似乎正常通过...java.security.NoSuchProviderException: no such provider: BC我们单独运行时,它们会失败,因为我们明确指定了提供程序.我无法将以下JDK JCE加密代码映射到Bouncy Castles Light-weight API:
public String dec(String password, String salt, String encString) throws Throwable {
// AES algorithm with CBC cipher and PKCS5 padding
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
// Construct AES key from salt and 50 iterations
PBEKeySpec pbeEKeySpec = new PBEKeySpec(password.toCharArray(), toByte(salt), 50, 256);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithSHA256And256BitAES-CBC-BC");
SecretKeySpec secretKey = new SecretKeySpec(keyFactory.generateSecret(pbeEKeySpec).getEncoded(), "AES");
// IV seed for first block taken from first 32 bytes
byte[] ivData = toByte(encString.substring(0, 32));
// AES encrypted data
byte[] encData = …Run Code Online (Sandbox Code Playgroud) 我使用BouncyCastle创建证书
var keypairgen = new RsaKeyPairGenerator();
keypairgen.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024));
var keypair = keypairgen.GenerateKeyPair();
var gen = new X509V3CertificateGenerator();
var CN = new X509Name("CN=" + certName);
var SN = BigInteger.ProbablePrime(120, new Random());
gen.SetSerialNumber(SN);
gen.SetSubjectDN(CN);
gen.SetIssuerDN(CN);
gen.SetNotAfter(DateTime.Now.AddYears(1));
gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7,0,0,0)));
gen.SetSignatureAlgorithm("MD5WithRSA");
gen.SetPublicKey(keypair.Public);
gen.AddExtension(
X509Extensions.AuthorityKeyIdentifier.Id,
false,
new AuthorityKeyIdentifier(
SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keypair.Public),
new GeneralNames(new GeneralName(CN)),
SN
));
gen.AddExtension(
X509Extensions.ExtendedKeyUsage.Id,
false,
new ExtendedKeyUsage(new ArrayList()
{
new DerObjectIdentifier("1.3.6.1.5.5.7.3.1")
}));
var newCert = gen.Generate(keypair.Private);
Run Code Online (Sandbox Code Playgroud)
这样结束了
X509Certificate2 certificate = new X509Certificate2(DotNetUtilities.ToX509Certificate((Org.BouncyCastle.X509.X509Certificate)newCert));
Run Code Online (Sandbox Code Playgroud)
现在,因为我的作业告诉我将证书和PrivateKey存储在X509Certificate2对象中,我需要一种方法将keypair.Private转换为X509Certificate2.Private.有任何想法吗?
谢谢.
首先让我说我对这一切都是新手.我想要做的是使用Java中的gpg来解密加密文件.
我成功完成了什么:
有同事使用我的公钥和他的私钥加密文件并成功解密它.
走了另一条路
让另一位同事尝试解密一个不适合他的文件:失败(如预期的那样)
我的密钥是这样生成的......
(gpg --version告诉我我正在使用1.4.5而我正在使用Bouncy Castle 1.47)
gpg --gen-ley
选择选项"DSA和Elgamal(默认)"
填写其他字段并生成密钥.
该文件使用我的公钥和另一个密钥加密.我想解密它.我编写了以下Java代码来完成此任务.我正在使用几种弃用的方法,但我无法弄清楚如何正确实现使用非弃用版本所需的工厂方法,所以如果有人对我应该使用的那些实现有一个想法,那将是一个不错的奖金.
Security.addProvider(new BouncyCastleProvider());
PGPSecretKeyRingCollection secretKeyRing = new PGPSecretKeyRingCollection(new FileInputStream(new File("test-files/secring.gpg")));
PGPSecretKeyRing pgpSecretKeyRing = (PGPSecretKeyRing) secretKeyRing.getKeyRings().next();
PGPSecretKey secretKey = pgpSecretKeyRing.getSecretKey();
PGPPrivateKey privateKey = secretKey.extractPrivateKey("mypassword".toCharArray(), "BC");
System.out.println(privateKey.getKey().getAlgorithm());
System.out.println(privateKey.getKey().getFormat());
PGPObjectFactory pgpF = new PGPObjectFactory(
new FileInputStream(new File("test-files/test-file.txt.gpg")));
Object pgpObj = pgpF.nextObject();
PGPEncryptedDataList encryptedDataList = (PGPEncryptedDataList) pgpObj;
Iterator objectsIterator = encryptedDataList.getEncryptedDataObjects();
PGPPublicKeyEncryptedData publicKeyEncryptedData = (PGPPublicKeyEncryptedData) objectsIterator.next();
InputStream inputStream = publicKeyEncryptedData.getDataStream(privateKey, "BC");
Run Code Online (Sandbox Code Playgroud)
因此,当我运行此代码时,我了解到我的密钥的算法和格式如下:
算法:DSA格式:PKCS#8
然后它在最后一行打破:
Exception in thread "main" org.bouncycastle.openpgp.PGPException: error …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个自签名的可信证书.我正在使用nuget的Bouncy Castle,以及这个问题的答案.这是该页面上的代码:
public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey, int keyStrength = 2048)
{
// Generating Random Numbers
var randomGenerator = new CryptoApiRandomGenerator();
var random = new SecureRandom(randomGenerator);
// The Certificate Generator
var certificateGenerator = new X509V3CertificateGenerator();
// Serial Number
var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
certificateGenerator.SetSerialNumber(serialNumber);
// Signature Algorithm
const string signatureAlgorithm = "SHA256WithRSA";
certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);
// Issuer and Subject Name
var subjectDN = new X509Name(subjectName);
var issuerDN = issuerName;
certificateGenerator.SetIssuerDN(issuerDN);
certificateGenerator.SetSubjectDN(subjectDN);
// Valid For
var …Run Code Online (Sandbox Code Playgroud) bouncycastle ×10
java ×5
c# ×3
cryptography ×3
.net ×2
android ×2
aes ×1
elgamal ×1
https ×1
jce ×1
keystore ×1
mockito ×1
openpgp ×1
pbkdf2 ×1
pkcs#8 ×1
private-key ×1
rfc3161 ×1
robolectric ×1
trust ×1
x509 ×1