我正在使用 Bouncy Castle 生成 ECC 密钥对:
KeyPairGenerator kpg = null;
try {
kpg = KeyPairGenerator.getInstance("ECDH", BouncyCastleProvider.PROVIDER_NAME);
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
throw new CustomException("Exception: " + e.getMessage());
}
try {
kpg.initialize(paramSpec, new SecureRandom());
} catch (InvalidAlgorithmParameterException e) {
throw new CustomException("Exception: " + e.getMessage());
}
return kpg.generateKeyPair();
Run Code Online (Sandbox Code Playgroud)
的类型paramSpec来自ECParameterSpec. java.security.spec我在用着brainpoolP256r1。
效果很好。然后我想将密钥对中的公钥值(来自 EC 公共点的 X 和 Y 坐标)转换为八位字节字符串。
为此,我使用BigInteger.toByteArray()函数。
我的问题和我想要理解的是为什么坐标的大小并不总是相同?
每个坐标应为 32 字节。但有时,我会得到 31 字节或 33 字节。toByteArray()据我所知,它与返回一个包含此 BigInteger 的补码表示的 …
我使用“secp256r1”曲线创建了一个 EC 密钥对。它是256位曲线,私钥应该是256位(32字节)。但我得到的是 39 字节的私钥。这是我的代码
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC"); //Provider is SunEC version 1.8
ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1");
kpg.initialize(ecSpec, new SecureRandom());
KeyPair ecKeyPair = kpg.generateKeyPair();
PrivateKey privateKey = ecKeyPair.getPrivate();
ASN1Sequence sequence = DERSequence.getInstance(privateKey.getEncoded());
DEROctetString subjectPrivateKey = (DEROctetString) sequence.getObjectAt(2);
byte[] privateKeyBytes = subjectPrivateKey.getOctets();
System.out.println("PrivateKeyBytes.length: " + privateKeyBytes.length); // Expected length is 32, but actual is 39
Run Code Online (Sandbox Code Playgroud)
我正在使用 JDK 1.8.0_144 和 BouncyCastle 库。这是pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>pki</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencies>
<dependency> …Run Code Online (Sandbox Code Playgroud) 我使用 Bouncy Castle 生成 PEM 格式的 ECC 密钥对:
var curve = ECNamedCurveTable.GetByName("secp256k1");
var domainParams = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed());
var secureRandom = new SecureRandom();
var keyParams = new ECKeyGenerationParameters(domainParams, secureRandom);
var generator = new ECKeyPairGenerator("ECDSA");
generator.Init(keyParams);
AsymmetricCipherKeyPair keyPair = generator.GenerateKeyPair();
TextWriter textWriter = new StringWriter();
PemWriter pemWriter = new PemWriter(textWriter);
pemWriter.WriteObject(keyPair.Private);
pemWriter.Writer.Flush();
string pem_privatekey = textWriter.ToString();
Run Code Online (Sandbox Code Playgroud)
我当前的 ECC 私钥是:
-----BEGIN EC PRIVATE KEY-----MIIBUQIBAQQgyDHBaj30dcIsS4otdOXR8ue+rZDwHcGEjxwle3H24W6ggeMwgeACAQEwLAYHKoZIzj0BAQIhAP////////////////////////////////////7///wvMEQEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwRBBHm+Zn753LusVaBilc6HCwcCm/zbLc4o2VnygVsW+BeYSDradyajxGVdpPv8DhEIqP0XtEimhVQZnEfQj/sQ1LgCIQD////////////////////+uq7c5q9IoDu/0l6M0DZBQQIBAaFEA0IABHxw0PK0uEvnF1lwhkLmHUlVtQVUrLp/1EcKzfAm6xOL/I6LtQ9nXPxDNhaxf/rPtk3DkZ5CaO0hLr1trCRrJz8=-----END EC PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
ECPrivateKeyParameters我想以充气城堡或格式私下阅读此 pem 格式AsymmetricCipherKeyPair 。我正在尝试以下代码。
pem就是上面的私钥字符串。
PemReader pr = new …Run Code Online (Sandbox Code Playgroud) java我正在使用bouncy castle库加载公钥,但总是出现错误Invalid point encoding 0x45。
公钥是使用 C# CNG API 在客户端生成的。
Java方法1:
public PublicKey loadPublicKey(String encodedPublicKey)
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException {
byte[] keybytes = java.util.Base64.getDecoder().decode(encodedPublicKey);
Security.addProvider(new BouncyCastleProvider());
ECNamedCurveParameterSpec params = ECNamedCurveTable.getParameterSpec("P-256");
ECPublicKeySpec keySpec = new ECPublicKeySpec(params.getCurve().decodePoint(keybytes), params);
return new BCECPublicKey("ECDH", keySpec, BouncyCastleProvider.CONFIGURATION);
}
Run Code Online (Sandbox Code Playgroud)
方法二
public PublicKey loadPublicKey(String pKey) throws Exception {
byte[] keybytes = java.util.Base64.getDecoder().decode(pKey);
Security.addProvider(new BouncyCastleProvider());
ECParameterSpec params = ECNamedCurveTable.getParameterSpec("P-256");
ECPublicKeySpec pubKey = new ECPublicKeySpec(params.getCurve().decodePoint(keybytes), params);
KeyFactory kf = KeyFactory.getInstance("ECDH", "BC");
return kf.generatePublic(pubKey);
}
Run Code Online (Sandbox Code Playgroud)
例外 …
我需要解密 AES 消息。我能够使其在 python 上工作(使用 pycryptodome 库),但在 kotlin/java 上没有成功。由于解密模式是OCB,而Java默认不支持它,所以我不得不使用Bouncy Castle库。
这是工作的 python 代码:
def decrypt_aes_message(shared_key, encrypted_message):
encrypted_msg = b64decode(encrypted_message["encryptedMessage"].encode())
tag = b64decode(encrypted_message["tag"].encode())
nonce = b64decode(encrypted_message["nonce"].encode())
cipher = AES.new(shared_key.encode(), AES.MODE_OCB, nonce=nonce)
return cipher.decrypt_and_verify(encrypted_msg, tag).decode()
Run Code Online (Sandbox Code Playgroud)
这是java代码:
fun decryptAesMessage2(sharedKey: String, encryptedMessageData: Map<String, String>): ByteArray {
var encryptedMessage = encryptedMessageData["encryptedMessage"]!!.utf8Base64Decode()
var tag = encryptedMessageData["tag"]!!.utf8Base64Decode()
var nonce = encryptedMessageData["nonce"]!!.utf8Base64Decode()
var key = KeyParameter(sharedKey.toByteArray(Charsets.UTF_8))
var params = AEADParameters(key, tag.size*8, nonce)
var cipher = OCBBlockCipher(AESEngine(), AESEngine())
cipher.init(false, params)
val out = ByteArray(cipher.getOutputSize(encryptedMessage.size))
var offset = cipher.processBytes(encryptedMessage, 0, …Run Code Online (Sandbox Code Playgroud) 我在我的应用程序的不同部分使用bouncycastle org.bouncycastle.jce.provider.X509CertificateObject和sun.security.x509.X509CertImpl,有时我需要比较它们是否相等,equals()方法不起作用以及像getSubjectDN这样的方法().getName()为每个实现显示不同的结果,如何在不进行二进制DER或PEM比较的情况下比较这些证书的相等性?
以下测试设置在Android模拟器上运行正常.它使用相互身份验证打开与外部服务器的基于SSL/TLS的连接:
ca.crt(验证服务器证书):
----- BEGIN CERTIFICATE -----
BASE64编码 -
-----结束证书-----
client.p12(包括由服务器信任的私有CA签名的客户端证书):PKCS#12格式
运行成功的Java/Android代码:
trustStore = KeyStore.getInstance("bks");
trustStore.load(null, null);
caCertificate = getX509Certificate("/some/path/ca.crt");
trustStore.setCertificateEntry("ca-cert", caCertificate);
keyStore = KeyStore.getInstance("pkcs12");
keyStore.load(null, null);
InputStream is = new FileInputStream("/some/path/client.p12");
keyStore.load(is, "passwd".toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("X509");
trustManagerFactory.init(trustStore);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509");
keyManagerFactory.init(keyStore, null);
context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
URL url = new URL("https://www.backend.com");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(context.getSocketFactory());
connection.setDoInput(true);
connection.setDoInput(true);
BufferedReader urlReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
while ( (inputLine=urlReader.readLine()) != null ){
System.out.println(inputLine);
} …Run Code Online (Sandbox Code Playgroud) 我正在寻找卷曲的Java包装器.我理解Java对于http和https连接(即标准以及Apache http客户端)具有出色的api.我有一个场景,我的https连接需要通过FIPS认证的加密引擎.由于Openssl是通过FIPS验证并且curl使用它作为后端的,我想知道是否有一个易于使用的curl lib包装器.
随机附带的Bouncycastle加密不是fips认证.
嘿,我是java和android的新手.尝试与海绵城堡一起锻炼,但有一些问题.我试着在后解决这个,但仍然得到运行时错误"应用程序已意外停止,请重试".
这是代码:
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.ECGenParameterSpec;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import org.spongycastle.jce.provider.BouncyCastleProvider;
public class MainActivity extends Activity {
static {
//Security.addProvider(new BouncyCastleProvider());
Security.insertProviderAt(new BouncyCastleProvider(), 1);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button generator= (Button) findViewById(R.id.key_pair_generator);
generator.setOnClickListener(ECkeyPairGenerator);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return …Run Code Online (Sandbox Code Playgroud) 我想使用PKCS7容器在PDF文件中创建分离的签名。数据(哈希)已预先使用私钥在其他设备上签名。我想创建一个包含签名数据以及带有公钥的证书的PKCS7。如果没有提供私钥并使库对数据进行签名,我似乎无法创建带有弹力城堡的PKCS7。这似乎不起作用:
InputStream inStream = new FileInputStream("1_public.pem");
BufferedInputStream bis = new BufferedInputStream( inStream );
CertificateFactory cf = CertificateFactory.getInstance("X.509");
List<Certificate> certList = new ArrayList<Certificate>();
Certificate certificate = cf.generateCertificate(bis);
certList.add(certificate);
Store certs = new JcaCertStore(certList);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
gen.addCertificates( certs );
CMSProcessableInputStream msg = new CMSProcessableInputStream( new ByteArrayInputStream( "signedhash".getBytes() ) );
CMSSignedData signedData = gen.generate(msg, false);
byte[] pkcs7 = signedData.getEncoded() ) );
Run Code Online (Sandbox Code Playgroud) bouncycastle ×10
java ×8
cryptography ×4
android ×2
c# ×2
aes ×1
compression ×1
curl ×1
ecdsa ×1
fips ×1
kotlin ×1
openssl ×1
pkcs#7 ×1
pki ×1
private-key ×1
ssl ×1
x509 ×1