令人惊讶的是,网上关于使用Bouncy Castle的轻量级API的信息非常少.环顾四周后,我能够把一个基本的例子放在一起:
RSAKeyPairGenerator generator = new RSAKeyPairGenerator();
generator.init(new RSAKeyGenerationParameters
(
new BigInteger("10001", 16),//publicExponent
SecureRandom.getInstance("SHA1PRNG"),//prng
1024,//strength
80//certainty
));
AsymmetricCipherKeyPair keyPair = generator.generateKeyPair();
Run Code Online (Sandbox Code Playgroud)
我有RSA的一个基本的了解,并且会在幕后数学,让我明白了什么publicExponent和strength是.我认为只要使用适当的填充,我publicExponent指的是互质phi(pq)并且从我收集的它可以是小的(如3).但是,我不知道是certainty指什么(某些地方提到它可能指的是一个百分比,但我想确定).使用SecureRandom是不言自明的.RSAKeyGenerationParameters的文档完全没有价值(毫不奇怪).我唯一的猜测是它与生成的键的准确性有关,但我想再次确定.所以我的问题是什么是适当的价值certainty和publicExponent?
PS请不要回复"这取决于具体情况 - 您希望信息的安全性".假设最高程度的安全性(即4096位RSA密钥或更高)是非常安全的,除非另有说明......我还希望链接到能够提供使用Bouncy Castle轻量级API的良好示例的链接(我不是所有对JCA实施感兴趣或任何与之相关的例子).
我在我的C#项目中使用RSA(Bouncy Castle API).我用这个方法生成了密钥对:
RsaKeyPairGenerator r = new RsaKeyPairGenerator();
r.Init(new KeyGenerationParameters(new SecureRandom(), 1024));
AsymmetricCipherKeyPair keys = r.GenerateKeyPair();
AsymmetricKeyParameter private_key = keys.Private;
AsymmetricKeyParameter public_key = keys.Public;
Run Code Online (Sandbox Code Playgroud)
现在我想将它们保存在txt文件中,但问题是我无法将它们转换为字符串格式.我在另一篇文章中读到必须使用以下序列化密钥:
PrivateKeyInfo k = PrivateKeyInfoFactory.CreatePrivateKeyInfo(private_key);
byte[] serializedKey = k.ToAsn1Object().GetDerEncoded();
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?如果是,那我该怎么办?只需将它们从byte []转换为String?
我有一个使用Bouncy Castle进行PGP解密的应用程序,在过去的8个月左右没有任何问题,过去2天突然出现了GetDataStream方法引发异常的问题:
异常消息:"错误设置非对称密码".
内部异常消息:"不是RSA密钥".
private static PgpObjectFactory getClearDataStream(PgpPrivateKey privateKey, PgpPublicKeyEncryptedData publicKeyED)
{
// Exception throws here.
Stream clearStream = publicKeyED.GetDataStream(privateKey);
PgpObjectFactory clearFactory = new PgpObjectFactory(clearStream);
return clearFactory;
}
Run Code Online (Sandbox Code Playgroud)
密钥尚未过期,没有到期日期:

我没有对应用程序进行任何更改,我没有触及按键,所以我不太明白为什么一个问题突然出现了.有任何想法吗?我也可以使用我在应用程序中加载的相同密钥使用Kleopatra手动解密文件.
更新1 - 我下载了OpenPGP Library for .NET的免费试用版,它也希望使用BouncyCastle,我也没有问题使用相同的密钥解密文件.出于某种原因,我使用已经工作了几个月的BouncyCastle实现的解密由于某种原因而停止工作,我还无法识别.
更新2 - 我上周提取的文件有效,我还下载了BouncyCastle的源代码,以便我可以单步调试以查看异常抛出的位置以及变量在工作和一个不起作用的文件.在PgpPublicKeyEncryptedData类的GetDataStream方法的开头抛出异常:
byte[] plain = fetchSymmetricKeyData(privKey);
Run Code Online (Sandbox Code Playgroud)
当我进入这个方法时,对于我可以解密而没有任何问题的文件,我注意到keyData.Algorithm变量设置为"ElGamalEncrypt",而对于异常抛出的文件,文件keyData.Algortithm设置为"RsaGeneral".为什么这些不同?公司向我发送文件是否更改了加密方法?BouncyCastle是否未正确支持此加密方法?
private byte[] fetchSymmetricKeyData(PgpPrivateKey privKey)
{
IBufferedCipher c1 = GetKeyCipher(keyData.Algorithm);
try
{
c1.Init(false, privKey.Key);
}
catch (InvalidKeyException e)
{
throw new PgpException("error setting asymmetric cipher", e);
}
Run Code Online (Sandbox Code Playgroud)
此外,不确定这是否相关,我们的密钥的证书类型是DSA.

更新3 - 在给定当前密钥的情况下,我一直无法弄清楚如何解决问题.我昨天生成了新密钥(类型为DSA),并且使用新密钥解决了问题.
更新4 - 这个问题刚刚出现,我的上一次更新中使用了新密钥.现在,PgpPublicKeyEncryptedData类中的keyData.Algorithm再次被看作"RsaGeneral"而不是"ElGamalEncrypt".为什么Algorithm属性会改变?加密文件的人是在改变什么吗?
我需要在C#中加密数据,以便将其传递给Java.Java代码属于第三方但我得到了相关的来源,所以我决定,当Java使用Bouncy Castle库时,我将使用C#端口.
解密工作正常.但是,只有当我使用私钥加密而不使用公钥时,解密才有效.使用公钥时,解密失败unknown block type.
显然加密时内部加密RsaEncryptWithPrivate使用公钥,所以我不明白为什么这两种加密方法在功能上不相同:
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.OpenSsl;
public class EncryptionClass
{
public string RsaEncryptWithPublic(string clearText
, string publicKey)
{
var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText);
var encryptEngine = new Pkcs1Encoding(new RsaEngine());
using (var txtreader = new StringReader(publicKey))
{
var keyParameter = (AsymmetricKeyParameter)new PemReader(txtreader).ReadObject();
encryptEngine.Init(true, keyParameter);
}
var encrypted = Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length));
return encrypted;
}
public string RsaEncryptWithPrivate(string clearText
, string privateKey)
{
var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText);
var encryptEngine = new …Run Code Online (Sandbox Code Playgroud) 我正在创建一个证书分发系统来跟踪客户和东西.
会发生什么:
所以在客户端会发生这种情况:
//Pseudo Server Object:
Server s = new Server();
//Requested Certificate Name and things
X509Name name = new X509Name("CN=Client Cert, C=NL");
//Key generation 2048bits
RsaKeyPairGenerator rkpg = new RsaKeyPairGenerator();
rkpg.Init(new KeyGenerationParameters(new SecureRandom(), 2048));
AsymmetricCipherKeyPair ackp = rkpg.GenerateKeyPair();
//PKCS #10 Certificate Signing Request
Pkcs10CertificationRequest csr = new Pkcs10CertificationRequest("SHA1WITHRSA", name, ackp.Public, null, ackp.Private);
//Make it a nice PEM thingie
StringBuilder sb = new StringBuilder();
PemWriter pemwrit = new PemWriter(new StringWriter(b));
pemwrit.WriteObject(csr);
pemwrit.Writer.Flush();
s.SendRequest(sb.ToSting());
Run Code Online (Sandbox Code Playgroud)
好吧我会跳过服务器端只要相信我服务器签署证书并将其发送回客户端.多数民众赞成在那里我会采取行动.
PemReader pr …Run Code Online (Sandbox Code Playgroud) 通过bouncycastle wiki页面,我能够理解如何创建X.509根证书和认证请求,但我不太明白如何在此之后继续进行概念和编程.
让我们假设甲方做了一个证书请求,并从CA获得了他的客户证书.某些乙方如何验证A的证书?A需要什么样的证书?根证书?"普通"客户证书?
如果我们假设A已成功将他的证书以DER或PEM格式发送给B,那么验证如何在编程级别上工作?
任何帮助深表感谢.
最诚挚的问候,Rob
我正在尝试将BouncyCastle添加为Windows XP Pro上的安全提供程序,因此我可以使用它根据此处的说明向Android应用程序添加一些证书.不幸的是我不能让它添加提供者.
我有:
C:\Program Files\Java\jre6\lib\ext\.C:\Program Files\Java\jre6\lib\ext\bcprov-jdk16-146.jar到%CLASSPATH%.security.provider.7=org.bouncycastle.jce.provider.BouncyCastleProvider到java.security(7是顺序中的下一个int).当我跑:
keytool -import -v -trustcacerts -alias 0 -file mycert.crt -keystore mystore.bks -storetype BKS -providerName org.bouncycastle.jce.provider.BouncyCastleProvider -storepass mypassword
Run Code Online (Sandbox Code Playgroud)
我收到以下错误消息:
keytool error: java.lang.ClassNotFoundException: org.bouncycastle.jce.provider.BouncyCastleProvider
Run Code Online (Sandbox Code Playgroud)
我也试过动态添加它:
import java.security.Provider;
import java.security.Security;
import java.util.Enumeration;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class BouncyCastleMain {
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider()); // add it
try { // list them out
Provider p[] = Security.getProviders();
for (int i …Run Code Online (Sandbox Code Playgroud) 我在localmachine的根证书存储中插入带有私钥的新CA证书时遇到问题.
这是发生的事情:
//This doesn't help either.
new StorePermission (PermissionState.Unrestricted) { Flags = StorePermissionFlags.AddToStore }.Assert();
var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
privkey.PersistKeyInCsp = true;
//This shouldn't be necessary doesn't make a difference what so ever.
RSACryptoServiceProvider.UseMachineKeyStore = true;
cert.PrivateKey = privkey;
store.Open (OpenFlags.MaxAllowed);
store.Add (cert);
store.Close ();
Run Code Online (Sandbox Code Playgroud)
证书被插入,它看起来都很花哨:(见!) 
注意:据说它有一个私钥.
所以你会说用FindPrivateKey可以找到它
C:\Users\Administrator\Desktop>FindPrivateKey.exe Root LocalMachine -t "54 11 b1 f4 31 99 19 d3 5a f0 5f 01 95 fc aa 6f 71 12 13 eb"
FindPrivateKey failed for the following …Run Code Online (Sandbox Code Playgroud) 我使用"BouncyCastle.Crypto.dll"来加密/解密我的应用程序中的字符串.我正在使用此博客中的以下代码:
我有一个BCEngine类,与上面提到的链接完全相同.
public class BCEngine
{
private readonly Encoding _encoding;
private readonly IBlockCipher _blockCipher;
private PaddedBufferedBlockCipher _cipher;
private IBlockCipherPadding _padding;
public BCEngine(IBlockCipher blockCipher, Encoding encoding)
{
_blockCipher = blockCipher;
_encoding = encoding;
}
public void SetPadding(IBlockCipherPadding padding)
{
if (padding != null)
_padding = padding;
}
public string Encrypt(string plain, string key)
{
byte[] result = BouncyCastleCrypto(true, _encoding.GetBytes(plain), key);
return Convert.ToBase64String(result);
}
public string Decrypt(string cipher, string key)
{
byte[] result = BouncyCastleCrypto(false, Convert.FromBase64String(cipher), key);
return …Run Code Online (Sandbox Code Playgroud)也许我的期望是错的.我不是加密专家,我只是一个简单的用户.到目前为止,我已经详尽地试图使这项工作取得成功.
背景资料:
我正在尝试从Delphi Encryption Compendium移植Legacy Encryption,它使用Blowfish Engine(TCipher_Blowfish_)和CTS操作模式(cmCTS).私钥由RipeMD256(THash_RipeMD256)进行哈希处理.
问题:
输入纯文本字节数组的大小必须相同CIPHER_BLOCK.据我所知,它不应该.
来自维基百科:
在密码学中,密文窃取(CTS)是使用分组密码操作模式的一般方法,其允许处理不可均分成块的消息而不会导致密文的任何扩展,代价是稍微增加了复杂性.
输出与旧例程不同:
我正在使用:
遗留应用程序使用ANSI String,新的使用Unicode,因此对于我调用的每个输入字符串Encoding.ASCII.GetBytes("plainText"),Encoding.ASCII.GetBytes("privatepassword").
然后由RipeMD256对私有密码字节进行散列,我检查了输出字节,它们是相同的.
我可以确认问题在Bouncy Clastle(操作模式或缺少配置/步骤)中是特定的,因为我已经下载了第二个库Blowfish.cs并使用8字节的输入(与密码块大小相同)并使用Encrypt_CBC(bytes[])with相同的IV产生与传统格式相同的输出.
这是我使用两个代码的草图Blowfish.cs和Bouncy Castle:
var
IV: Array [0..7] of Byte (1,2,3,4,5,6,7,8);
Key: String = '12345678';
with TCipher_Blowfish.Create('', nil) do
begin
try
InitKey(Key, @IV); //Key is auto hashed using RIPE256 here;
Result:= CodeString('12345678', paEncode, -1); //Output bytes is later encoded as …Run Code Online (Sandbox Code Playgroud) bouncycastle ×10
c# ×6
encryption ×4
rsa ×4
java ×3
certificate ×2
cryptography ×2
.net ×1
.net-4.0 ×1
csr ×1
delphi ×1
pgp ×1
security ×1
validation ×1
x509 ×1