![](/img/trans.png)
[英]GoDaddy SSL Certificate installation in tomcat… No certificate matches private key
[英]How to verify if the private key matches with the certificate..?
我将私钥存储为.key文件..
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQD5YBS6V3APdgqaWAkijIUHRK4KQ6eChSaRWaw9L/4u8o3T1s8J
rUFHQhcIo5LPaQ4BrIuzHS8yzZf0m3viCTdZAiDn1ZjC2koquJ53rfDzqYxZFrId
7a4QYUCvM0gqx5nQ+lw1KoY/CDAoZN+sO7IJ4WkMg5XbgTWlSLBeBg0gMwIDAQAB
AoGASKDKCKdUlLwtRFxldLF2QPKouYaQr7u1ytlSB5QFtIih89N5Avl5rJY7/SEe
rdeL48LsAON8DpDAM9Zg0ykZ+/gsYI/C8b5Ch3QVgU9m50j9q8pVT04EOCYmsFi0
DBnwNBRLDESvm1p6NqKEc7zO9zjABgBvwL+loEVa1JFcp5ECQQD9/sekGTzzvKa5
SSVQOZmbwttPBjD44KRKi6LC7rQahM1PDqmCwPFgMVpRZL6dViBzYyWeWxN08Fuv
p+sIwwLrAkEA+1f3VnSgIduzF9McMfZoNIkkZongcDAzjQ8sIHXwwTklkZcCqn69
qTVPmhyEDA/dJeAK3GhalcSqOFRFEC812QJAXStgQCmh2iaRYdYbAdqfJivMFqjG
vgRpP48JHUhCeJfOV/mg5H2yDP8Nil3SLhSxwqHT4sq10Gd6umx2IrimEQJAFNA1
ACjKNeOOkhN+SzjfajJNHFyghEnJiw3NlqaNmEKWNNcvdlTmecObYuSnnqQVqRRD
cfsGPU661c1MpslyCQJBAPqN0VXRMwfU29a3Ve0TF4Aiu1iq88aIPHsT3GKVURpO
XNatMFINBW8ywN5euu8oYaeeKdrVSMW415a5+XEzEBY=
-----END RSA PRIVATE KEY-----
我从ssl证书文件中提取了公钥。
下面是我试图验证私钥是否与ssl证书匹配的代码。
我使用模数[即私钥获取模数==公钥获取模数]来检查它们是否匹配..
这似乎只适用于RSAKEYS ..
但我想检查其他钥匙..
有没有其他选择做同样的事情。??
private static boolean verifySignature(File serverCertificateFile, File serverCertificateKey) {
try {
byte[] certificateBytes = FileUtils.readFileToByteArray(serverCertificateFile);
//byte[] keyBytes = FileUtils.readFileToByteArray(serverCertificateKey);
RandomAccessFile raf = new RandomAccessFile(serverCertificateKey, "r");
byte[] buf = new byte[(int) raf.length()];
raf.readFully(buf);
raf.close();
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(buf);
KeyFactory kf;
try {
kf = KeyFactory.getInstance("RSA");
RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(kspec);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(certificateBytes);
//Generate Certificate in X509 Format
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(in);
RSAPublicKey publicKey = (RSAPublicKey) cert.getPublicKey();
in.close();
return privKey.getModulus() == publicKey.getModulus();
} catch (NoSuchAlgorithmException ex) {
logger.log(Level.SEVERE, "Such algorithm is not found", ex);
} catch (CertificateException ex) {
logger.log(Level.SEVERE, "certificate exception", ex);
} catch (InvalidKeySpecException ex) {
Logger.getLogger(CertificateConversion.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (IOException ex) {
logger.log(Level.SEVERE, "Signature verification failed.. This could be because the file is in use", ex);
}
return false;
}
并且代码也不起作用..抛出invalidkeyspec异常
使用私钥对某些内容进行签名,并使用证书中的公钥对其进行验证。 除非他们是一对,否则这将失败。
那么,成对参数检查的问题是什么?
n
, e
。 p
, q
, g
, y
。 等等,即每个算法都需要自己正确的处理。 如果密钥文件格式实际上是自定义的,则不存在通用算法。 但是,您仍可以通过仅指定值索引来略微概括它:
ComparisonScheme = new Dictionary<String, Integer[2][]> {
{ "RSA", {{0, 0}, {1, 1}} },
{ "DSA", {{0, 1}, {1, 2}, {2, 3}, {3, 0}} },
}
当然,这只是一个例子 - 不要认真对待语法和数字。
如果要检查,如果RSA publicKey和RSA privateKey属于一起,则可以使用以下代码:
RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;
return rsaPublicKey.getModulus().equals( rsaPrivateKey.getModulus() )
&& BigInteger.valueOf( 2 ).modPow( rsaPublicKey.getPublicExponent()
.multiply( rsaPrivateKey.getPrivateExponent() ).subtract( BigInteger.ONE ),
rsaPublicKey.getModulus() ).equals( BigInteger.ONE );
我正在为EC寻找类似的解决方案......
到目前为止,我们已经找到了ECC的方法:但是它有点复杂:
ECPublicKey pk = (ECPublicKey) publicKey;
ECPrivateKey sk = (ECPrivateKey) privateKey;
ECParameterSpec pkSpec = pk.getParams(), skSpec = sk.getParams();
EllipticCurve skCurve = skSpec.getCurve(), pkCurve = pkSpec.getCurve();
ECField skField = skCurve.getField(), pkField = pkCurve.getField();
BigInteger skA = skCurve.getA(), skB = skCurve.getB();
if ( pkSpec != skSpec //
&& ( pkSpec.getCofactor() != skSpec.getCofactor() //
|| ! pkSpec.getOrder().equals( skSpec.getOrder() ) //
|| ! pkSpec.getGenerator().equals( skSpec.getGenerator() ) //
|| pkCurve != skCurve //
&& ( ! pkCurve.getA().equals( skA ) //
|| ! pkCurve.getB().equals( skB ) //
|| skField.getFieldSize() != pkField.getFieldSize() ) ) ) //
return false;
ECPoint w = pk.getW();
BigInteger x = w.getAffineX(), y = w.getAffineY();
if ( skField instanceof ECFieldFp ) {
BigInteger skP = ( (ECFieldFp) skField ).getP();
return pkField instanceof ECFieldFp && skP.equals( ( (ECFieldFp) pkField ).getP() ) //
&& y.pow( 2 ).subtract( x.pow( 3 ) ).subtract( skA.multiply( x ) ).subtract( skB ).mod( skP ).signum() == 0;
}
if ( skField instanceof ECFieldF2m ) {
int m = ( (ECFieldF2m) skField ).getM();
BigInteger rp = ( (ECFieldF2m) skField ).getReductionPolynomial();
if ( ! ( pkField instanceof ECFieldF2m ) || m != ( (ECFieldF2m) skField ).getM() || ! rp.equals( ( (ECFieldF2m) skField ).getReductionPolynomial() ) )
return false;
BigInteger x2 = f2mReduce( f2mMultiply( x, x ), rp, m );
return f2mReduce( f2mSum( f2mMultiply( y, y ), f2mMultiply( x, y ), f2mMultiply( x, x2 ), f2mMultiply( skA, x2 ), skB ), rp, m ).signum() == 0;
}
以下是数学辅助函数:
public static final BigInteger f2mSum( BigInteger ... values )
{
if ( values.length == 0 )
return BigInteger.ZERO;
BigInteger result = values[ 0 ];
for ( int i = values.length - 1; i > 0; i -- )
result = result.xor( values[ i ] );
return result;
}
public static final BigInteger f2mAdd( BigInteger a, BigInteger b )
{
return a.xor( b );
}
public static final BigInteger f2mSubtract( BigInteger a, BigInteger b )
{
return a.xor( b );
}
public static final BigInteger f2mMultiply( BigInteger a, BigInteger b )
{
BigInteger result = BigInteger.ZERO, sparse, full;
if ( a.bitCount() > b.bitCount() ) {
sparse = b;
full = a;
} else {
sparse = b;
full = a;
}
for ( int i = sparse.bitLength(); i >= 0; i -- )
if ( sparse.testBit( i ) )
result = result.xor( full.shiftLeft( i ) );
return result;
}
public static final BigInteger f2mReduce( BigInteger input, BigInteger reductionPolynom, int bitLength )
{
while ( input.bitLength() > bitLength )
input = input.xor( reductionPolynom.shiftLeft( input.bitLength() - reductionPolynom.bitLength() ) );
return input;
}
您的代码很好,只需添加以下内容:
String file = "qwerty";
byte[] fileBytes = file.getBytes();
byte[] digitalSignature = signData(fileBytes, privKey);
System.out.println("SIGNATURE MADE");
boolean verified;
verified = verifySig(fileBytes, publicKey, digitalSignature);
System.out.println("verified: " + verified) ;
public static byte[] signData(byte[] data, PrivateKey key) throws Exception {
Signature signer = Signature.getInstance("SHA256withRSA");
signer.initSign(key);
signer.update(data);
return (signer.sign());
}
public static boolean verifySig(byte[] data, PublicKey key, byte[] sig) throws Exception {
Signature signer = Signature.getInstance("SHA256withRSA");
signer.initVerify(key);
signer.update(data);
return (signer.verify(sig));
}
我对此有点生疏,但有一点帮助比没有好吗?
通常,一旦拥有公钥/私钥,您就应该能够使用密码使用一个密钥加密一些少量数据,并查看是否可以使用另一个密钥成功解密。 这是一种蛮力,可能会影响性能,但可能适合你想要做的事情(我会提供代码,但我在一个我无法测试它的环境中,我不想发布任何内容如果你感兴趣, 使用RSA加密和解密java中的大字符串有使用密码的代码片段。
此外,除非标头已在您的示例私钥文件中被篡改,否则它不是PKCS8格式。 PKCS8文件不会在标头中指定算法(例如RSA),因为它们可以使用不同的算法,从而指定编码本身使用的算法。
另外,如果我没记错的话,原生java对PEM的支持很糟糕。 我相信您需要从密钥文件中删除PEM标头,然后base64对其进行解码,然后才能对其执行任何操作。 或者,如果可能,您可以确保您的密钥文件是DER编码的,在这种情况下,密钥规范应该读得很好。
如果椭圆曲线键匹配,此解决方案在我的情况下可用于初步检查:
boolean matches(PrivateKey privateKey, PublicKey publicKey) {
return ((ECKey) privateKey).getParams().equals(((ECKey) publicKey).getParams());
}
另见@ SteffenHeil对更多数学检查的答案,这些检查为我提供了相同的结果。
同样有趣的是,Apple Pay发行的商家支付处理证书与((ECKey) publicKey).getParams()
Apple)开发商关系CA-G2“父母”完全相同((ECKey) publicKey).getParams()
。 因此它们都匹配私钥,只有使用getSubjectDN()
= getIssuerDN()
检查才能解析叶子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.