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

时间:2018-10-24 11:04:59

标签: java certificate digital-signature bouncycastle

我正在使用Java中的以下代码来生成文件的数字签名。我正在将数字签名写入数据库。此数字签名是否与时间相关?因为每次我都为同一个文件获得不同的数字签名。
    我在同一时间在同一文件上获得不同的数字签名吗?

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();
            }
        }

}

输出:

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=

1 个答案:

答案 0 :(得分:0)

转到您选择的ASN.1解码器(or mine ;-),您会看到有签名日期和时间。很显然,每次签名数据时,签名日期和时间都会发生变化,从而导致签名不同。结果二进制数据。

在您给出的示例中,签名时间为

python manage.py createsuperuser