简体   繁体   English

在Java中使用BouncyCastle生成数字签名

[英]Generating Digital Signature using BouncyCastle in Java

I am generating digital signature for the file by using following code in java. 我正在使用Java中的以下代码来生成文件的数字签名。 And I am writing digital signature to database. 我正在将数字签名写入数据库。 Is this digital signature is time dependent? 此数字签名是否与时间相关? Because every time I am getting different digital signature for the same file. 因为每次我都为同一文件获得不同的数字签名。
Do I get different digital signature at different time for the same file? 我在同一时间在同一文件上得到不同的数字签名吗?

package generatesign;
import java.io.File;
import java.nio.file.Files; 
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.cert.X509Certificate;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;

import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.Store;

import sun.misc.BASE64Encoder;

public class SaveFileSign {
    static final String KEYSTORE_ALIAS = "GURU ESWARA RAO (1)";
    static final String KEYSTORE_PWD = "abcd@123";
    static final String DIGEST_SHA1 = "SHA1WithRSA";
    static final String BC_PROVIDER = "BC";

@SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String[] args) throws Exception {
    try {
        KeyStore ks;
        byte[] fileContent = Files.readAllBytes(new 
        File("F:\\myfile.xlsx").toPath());
        Security.addProvider(new BouncyCastleProvider());
        ks = KeyStore.getInstance("WINDOWS-MY", "SunMSCAPI");
        ks.load(null, KEYSTORE_PWD.toCharArray());
        Enumeration<String> aliases = ks.aliases();
        while (aliases.hasMoreElements()) {
            String alias = (String) aliases.nextElement();

            PrivateKey privkey = (PrivateKey) ks.getKey(KEYSTORE_ALIAS, 
            KEYSTORE_PWD.toCharArray());
            System.out.println("Private Key****" + privkey + "**");
            X509Certificate x509Certificate = (X509Certificate) 
            ks.getCertificate(alias);
            PublicKey publicKey = x509Certificate.getPublicKey();
            System.out.println("Public Key of " + KEYSTORE_ALIAS + "==" + 
            publicKey + "==");
            Signature signature = Signature.getInstance(DIGEST_SHA1);
            signature.initSign(privkey);
            signature.update(fileContent);

            // Build CMS
            X509Certificate certFromKeystore = (X509Certificate) 
            ks.getCertificate(KEYSTORE_ALIAS);
            List certList = new ArrayList();
            CMSTypedData data = new CMSProcessableByteArray(fileContent);
            certList.add(certFromKeystore);
            Store certs = new JcaCertStore(certList);





    CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
                    ContentSigner sha1Signer = new 
                    JcaContentSignerBuilder(DIGEST_SHA1).setProvider("SunMSCAPI")
                            .build(privkey);
                    gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
                            new JcaDigestCalculatorProviderBuilder().setProvider(BC_PROVIDER).build()).build(sha1Signer,
                                    certFromKeystore));
                    gen.addCertificates(certs);
                    CMSSignedData signedData = gen.generate(data, false); 
                    BASE64Encoder encoder = new BASE64Encoder();
                    String signedContent = encoder.encode((byte[]) signedData.getSignedContent().getContent());
                    System.out.println("=============Signed content:=============" + "\n" + signedContent + "***"
                            + signedContent.length() + "\n");
                    String envelopedData = encoder.encode(signedData.getEncoded());
                    System.out.println("==============Enveloped data===============" + "\n" + envelopedData + "***"
                            + envelopedData.length());

                    System.out.println("======Saving signature to DATABASE======");
                    // create a mysql database connection
                    String myDriver = "org.postgresql.Driver";
                    String myUrl = "jdbc:postgresql://localhost:5444/bmtcdemo";
                    Class.forName(myDriver);
                    Connection conn = DriverManager.getConnection(myUrl, "enterprisedb", "unibrain");
                    java.sql.Statement st = conn.createStatement();
                    PreparedStatement pst = conn.prepareStatement("INSERT INTO f_signature (sign) VALUES(?)");
                    pst.setString(1, envelopedData);
                    int i = pst.executeUpdate();
                    System.out.println("saved success====Rows affected====" + i);
                }

            } catch (Exception e) {
                e.getMessage();
            }
        }

}

Output: 输出:

MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIAwggXLMIIE
s6ADAgECAgQA4swkMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYDVQQGEwJJTjEqMCgGA1UEChMhZU11
ZGhyYSBDb25zdW1lciBTZXJ2aWNlcyBMaW1pdGVkMR0wGwYDVQQLExRDZXJ0aWZ5aW5nIEF1dGhv
cml0eTE0MDIGA1UEAxMrZS1NdWRocmEgU3ViIENBIGZvciBDbGFzcyAzIEluZGl2aWR1YWwgMjAx
NDAeFw0xODAxMTcxMzAxMzZaFw0yMDAxMTcxMzAxMzZaMIH6MQswCQYDVQQGEwJJTjERMA8GA1UE
ChMIUGVyc29uYWwxSTBHBgNVBBQTQDlGQkY0MjNBN0FFMTNFNDE4QzIwN0FBNDVDQTRFMzhGRjc3
MDRFMDc0NzcwQjlCOUEwQTBDRTYyNUM5RDFEOTQxDzANBgNVBBETBjUzMzI1NTEXMBUGA1UECBMO
QU5ESFJBIFBSQURFU0gxSTBHBgNVBAUTQDY5YzU5NGM2OTc4NmU2NDU2YmE5N2RkNjkwNmM1YjM5
ODhkODdjZmIwODFiMzQ2ZTFiY2FiMWEwYWI5Yjg4OWYxGDAWBgNVBAMTD0dVUlUgRVNXQVJBIFJB
TzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAME9iaVzUFc/v6axddTodLrgyXaqIPLi
4CBTMz4vPczgQnE+y+zFtivN0CZY7oUU9rC2BijrtSSWI+bxraXHmIRDPqkzLxK9RUvWqdjmAhMt
FcmA9nqyLJiVuK1uvfY+mLDcKFN/JKn/dpDTe9R2YZtW9JCm6N4J/xaDsmK0f1oauVUmsAdcMEIv
KAJTxyVbasrC635Y9u9zLlrQVhElxlhuaav+i1pmrzMim0cr+4a++fd7GdLeDvQgbCi59VWR3FEI
v25RJxlIT0NmeAqfxKZREoJYACdX3cejtbPJcKhP0bCH91p187eco9oBVVc1uVXMMMkdLTBIMD8i
UamqxjkCAwEAAaOCAcEwggG9MCIGA1UdEQQbMBmBF0dVUlUuRVNXQVIxMjNAR01BSUwuQ09NMBMG
A1UdIwQMMAqACEsxTuEApKl5MB0GA1UdDgQWBBT1YEZR2M1XNzBmO2dbdi0TCgg5HjAOBgNVHQ8B
Af8EBAMCBSAwgYwGA1UdIASBhDCBgTAtBgZggmRkAgMwIzAhBggrBgEFBQcCAjAVGhNDbGFzcyAz
IENlcnRpZmljYXRlMFAGB2CCZGQBCAIwRTBDBggrBgEFBQcCARY3aHR0cDovL3d3dy5lLW11ZGhy
YS5jb20vcmVwb3NpdG9yeS9jcHMvZS1NdWRocmFfQ1BTLnBkZjB7BggrBgEFBQcBAQRvMG0wJAYI
KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmUtbXVkaHJhLmNvbTBFBggrBgEFBQcwAoY5aHR0cDovL3d3
dy5lLW11ZGhyYS5jb20vcmVwb3NpdG9yeS9jYWNlcnRzL0MzSVNDQTIwMTQuY3J0MEcGA1UdHwRA
MD4wPKA6oDiGNmh0dHA6Ly93d3cuZS1tdWRocmEuY29tL3JlcG9zaXRvcnkvY3Jscy9DM0lTQ0Ey
MDE0LmNybDANBgkqhkiG9w0BAQsFAAOCAQEAUcMskDQi/c1UifNAJ7pZFF7FOf3seh0yNWt/8DdS
kw9WjNC3oR98bXnZf4kp0m3oIl7Lbha5uOrDPE2v1EDcpfGgWhzajLp2UsHDMOYi+rRvHxCjU2g9
dLkBJC/CLhb+ThVwwyhottLynYkveyk3l4f43e56k6TxuvR+UXG9WJXfXETWu4elwUr/jIbKavfl
nhd2mEgGxAbndHxeEEl4rAholxLyIot508mhHuWL0goD5TCdov6NNelNSqmsayNqmg4eEqc1A1fZ
s3fWsPNBpXC3BA+h93tZ6Pca5J1NZZo2LbFFea3fdNfds6dyecnWLFWf3CXeyWFbNMU0M4HBTwAA
MYICSjCCAkYCAQEwgZcwgY4xCzAJBgNVBAYTAklOMSowKAYDVQQKEyFlTXVkaHJhIENvbnN1bWVy
IFNlcnZpY2VzIExpbWl0ZWQxHTAbBgNVBAsTFENlcnRpZnlpbmcgQXV0aG9yaXR5MTQwMgYDVQQD
EytlLU11ZGhyYSBTdWIgQ0EgZm9yIENsYXNzIDMgSW5kaXZpZHVhbCAyMDE0AgQA4swkMAkGBSsO
AwIaBQCggYgwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTgxMDA0
MDkyNjExWjAjBgkqhkiG9w0BCQQxFgQUQsRy6DxQdjNDuPnZQJirv0pJcoAwKQYJKoZIhvcNAQk0
MRwwGjAJBgUrDgMCGgUAoQ0GCSqGSIb3DQEBAQUAMA0GCSqGSIb3DQEBAQUABIIBALQcToHFmxgS
B/sfk+XwtOntpLi/KyiSlkYJaeC27m0A0V44KgmKMIrHFzGBWSInMMUoaUWfkrWkbuxmB4rGx4hY
/US/2Ci6w11YXx9+U80RWtoDnUOD6VR7ezoWbgZf/N1Rep2SeY2Z81Zn63BSsOhFXGdBZku1523h
lWyBEJT068pB51/IPNxlCYwSrIDaeRbIug163ThYPYlpziOoFTHTnj0XgEamAc52Wnj2ENttnp1L
1uTj/KMfIoFuaRFIAxsKxLzeeWAO4zkhEw50mwt9wzLwch4tyeHP+/cLRCyjrQzKXA4vcg/OVl7u
P4uy+U7OOQipWFT2aZR0GKUFOpEAAAAAAAA=

Go to an ASN.1 decoder of your choice ( or mine ;-) and you will see that there is a signature date and time. 转到您选择的ASN.1解码器( 或我的;-) ,您将看到有签名的日期和时间。 Obviously this changes each time you sign the data leading to differing signatures if you look at the resulting binary data. 显然,每次查看数据时,这种情况都会改变,从而导致生成不同的签名(如果查看生成的二进制数据)。

In the your given example the signing time was 在您给定的示例中,签名时间为

OBJECT IDENTIFIER 1.2.840.113549.1.9.5 signingTime (PKCS #9)
    SET (1 elem)
        UTCTime 2018-10-04 09:26:11 UTC

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM