首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >修改X509证书

修改X509证书
EN

Stack Overflow用户
提问于 2014-02-20 16:40:03
回答 3查看 1.7K关注 0票数 4

我想要显示,如果我从给定的X509证书修改一个位或字节,签名验证结果是假的(因为这种修改会导致与证书不同的哈希值)。我陷入了这样的情况:如何使用getTBSCertificate()方法对证书进行修改。下面的代码完美地完成了验证过程,但我尝试使用位或字节修改的方法使其失败,但它不起作用。请注意,我提出的这个想法是,以证明证书上的任何修改都将导致签名验证失败。

代码语言:javascript
复制
public class VerifyX509 {

private static Certificate getCACert;
private static Certificate[] getCert;

public static void main(String[] args) throws CertificateEncodingException {
    setURLConnection("https://www.google.com");
    X509Certificate x509cert= (X509Certificate) getCert[0];
    byte[] b= x509cert.getTBSCertificate();
    b[0] = (byte) ~b[0];
    // HOW TO UPDATE getTBSCertificate() after flipping the b[0] to make Verify() in my method verifySign() return false!
    verifySign();

  }


public static void setURLConnection(String link){

    try{
        int i=1;
        URL destinationURL = new URL(link);
        HttpsURLConnection con = (HttpsURLConnection) destinationURL.openConnection();
        con.connect();
        getCert = con.getServerCertificates();
        for (Certificate c : getCert) 
        {
            if (i==2)
            {
                getCACert= c;
                return;
            }
            i+=1;
        }
        }catch (Exception e1) {
        JOptionPane.showMessageDialog(null, "Error while connection! Check your Internet Connection.");
        e1.printStackTrace();
        }

}


public static boolean verifySign()
{

        try
        {
            getCert[0].verify(getCACert.getPublicKey());
            return true;
        } catch (GeneralSecurityException e2)
        {
            return false;
        }
}
}

如何设置概念验证代码以证明验证失败?

EN

回答 3

Stack Overflow用户

发布于 2014-02-24 00:15:08

代码语言:javascript
复制
byte[] b= x509cert.getTBSCertificate();
b[0] = (byte) ~b[0];

更改从证书获得的数组中的字节不会更改证书。

您必须使用CertificateFactory.从字节数组重新加载它。

票数 1
EN

Stack Overflow用户

发布于 2014-02-23 02:37:39

Mike先生,您所要做的就是获取行数据DER编码的证书信息(TBS部件),您可以提取它,如下所示

代码语言:javascript
复制
URL url = new URL("https://www.google.com/");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.connect();
Certificate userCert[] = con.getServerCertificates();
        X509Certificate x509cert = ((X509Certificate) userCert[0]);


        byte[] tbs=x509cert.getTBSCertificate(); 

然后,通过循环将数组b的内容复制到另一个数组中,然后做您想做的任何修改(即使用掩蔽技术Anding和x55),然后您可以通过

代码语言:javascript
复制
    String sha1 = "";
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(bcopy);
        sha1 = byteToHex(crypt.digest());

private static String byteToHex(final byte[] hash)
{
    Formatter formatter = new Formatter();
    for (byte b : hash)
    {
        formatter.format("%02x", b);
    }
    String result = formatter.toString();
    formatter.close();
    return result;
}

此时您可以获得修改证书的哈希值,现在可以从原始证书[ byte[] sig= x509cert.getSignature(); ]中提取签名并解密签名以获得哈希值,并将其与修改后的哈希值进行比较,祝您好运;)

票数 0
EN

Stack Overflow用户

发布于 2017-08-11 22:33:16

如果您查看RFC 5280,证书有3个字段:

  • tbsCertificate
  • signatureAlgorithm
  • signatureValue

signatureValue是证书中的最后一项。

我也有类似的要求。以下是我遵循的步骤:

  • 有一个.crt格式的证书(基-64编码)文件.证书附在“
  • 在结束证书行之前的行中编辑证书的最后一个字符。只需将1加到该字符或将其减为1。如果最后一个字符为x,则将其改为y或w。

这将更改证书中的签名,并且签名将不再有效。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21917034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档