it-swarm-eu.dev

PKCS7-Codierung in Java ohne externe Bibliotheken wie BouncyCastle usw.

Ich arbeite an der Signierung und Codierung von CMS/PKCS # 7-Nachrichten (ähnlich wie C # SignedCms ).

Ich habe x509-Zertifikat aus dem Schlüsselspeicher, rsa privater Schlüssel,
ContentInfo. ContentType ist "oidPkcs7Data".

Ich verstehe nicht ganz, was ich als nächstes tun soll.

Ich dachte:

  1. generieren Sie eine Signatur und signieren Sie ContentInfo-Daten
 Signatur signatur = Signatur.getInstance ("MD5withRSA"); 
 Signatur.initSign (rsaPrivateKeyFromStore); 
 Signatur.Update (contentInfo.getData ()); 
 signiertData = Signatur.sign (); 
  1. codieren signierte Daten + Signatur.
 PKCS7 pkcs7 = neues PKCS7 (signierte Daten); 
 ByteArrayOutputStream baos = neues ByteArrayOutputStream (); 
 Pkcs7.encodeSignedData (baos); 

Aber ich habe die Ausnahme bekommen

 Sun.security.pkcs.ParsingException: Die codierten Bytes 
 In Sun.security.pkcs.PKCS7. (PKCS7.Java:94) 
 Können nicht analysiert werden.

Offensichtlich mache ich es falsch.

Ich würde es auch gerne ohne BouncyCastle oder Classpth oder so etwas machen.

Kann man nur Sun.security. * -Klassen verwenden? Ich benutze Java 1.5.

Ich bin neu in der DigitalSignature-Welt und jede Hilfe oder jeder Rat wird geschätzt.

UPD

Ich habe mein eigenes Zertifikat erstellt und versucht, die Daten damit zu signieren.

.Net-Code

        X509Certificate2 certificate = new X509Certificate2("X:\\mypfxstore.pfx", "123");
        String text = "text";
        ContentInfo contentInfo = new ContentInfo(System.Text.Encoding.UTF8.GetBytes(text));
        SignedCms cms = new SignedCms(contentInfo, false);
        CmsSigner signer = new CmsSigner(certificate);
        signer.IncludeOption = X509IncludeOption.None;
        signer.DigestAlgorithm = new Oid("SHA1");
        cms.ComputeSignature(signer, false);
        byte[] signature = cms.Encode();
        print(signature);

Java-Code

    char[] password = "123".toCharArray();
    String text = "text";

    FileInputStream fis = new FileInputStream("X:\\mypfxstore.pfx");
    KeyStore ks = KeyStore.getInstance("pkcs12");
    ks.load(fis, password);

    String alias = ks.aliases().nextElement();
    PrivateKey pKey = (PrivateKey)ks.getKey(alias, password);
    X509Certificate c = (X509Certificate)ks.getCertificate(alias);

    //Data to sign
    byte[] dataToSign = text.getBytes("UTF-8");
    //compute signature:
    Signature signature = Signature.getInstance("SHA1WithRSA");
    signature.initSign(pKey);
    signature.update(dataToSign);
    byte[] signedData = signature.sign();

    //load X500Name
    X500Name xName      = X500Name.asX500Name(c.getSubjectX500Principal());
    //load serial number
    BigInteger serial   = c.getSerialNumber();
    //laod digest algorithm
    AlgorithmId digestAlgorithmId = new AlgorithmId(AlgorithmId.SHA_oid);
    //load signing algorithm
    AlgorithmId signAlgorithmId = new AlgorithmId(AlgorithmId.RSAEncryption_oid);

    //Create SignerInfo:
    SignerInfo sInfo = new SignerInfo(xName, serial, digestAlgorithmId, signAlgorithmId, signedData);

    //Create ContentInfo:
    ContentInfo cInfo = new ContentInfo(ContentInfo.DIGESTED_DATA_OID, new DerValue(DerValue.tag_OctetString, dataToSign));

    //Create PKCS7 Signed data
    PKCS7 p7 = new PKCS7(new AlgorithmId[] { digestAlgorithmId }, cInfo,
            new Java.security.cert.X509Certificate[] { /*cert,*/ },
            new SignerInfo[] { sInfo });

    //Write PKCS7 to bYteArray
    ByteArrayOutputStream bOut = new DerOutputStream();
    p7.encodeSignedData(bOut);
    byte[] encoded = bOut.toByteArray();

    print(encoded);

Java-Ausgabe

length=264
3082010406092A864886F70D010702A081F63081F3020101310B300906052B0E03021A0500
301306092A864886F70D0 -> 10705A <- 0060404746578743181CB3081C8020101302630123110300E06
035504031307436F6D70616E790210FCAF9B5224FB4B9F4000B5127D881E2E300906052B0E0302
1A0500300D06092A864886F70D0101010500048180636ADD9F7E218AF3CBC5A75FA2076A53BE49
03DC864E87EBA3C1EE594FAACAFE93CA6F3410D847AC0C0ACB9FD88EC9CF6B00379FA9AD256C86
7204ED81E3FA2F8F492109FF87E81398B7B489B00A35914A2B51919DAAEC2BA87CEFB5AF52294E
2448B5B150D50A39BA0471A9AA1EA2B38A4E23BBA56E029842459F0D5BA3D511

Netzausgang

length=264
3082010406092A864886F70D010702A081F63081F3020101310B300906052B0E03021A0500
301306092A864886F70D0 -> 10701A <- 0060404746578743181CB3081C8020101302630123110300E06
035504031307436F6D70616E790210FCAF9B5224FB4B9F4000B5127D881E2E300906052B0E0302
1A0500300D06092A864886F70D0101010500048180636ADD9F7E218AF3CBC5A75FA2076A53BE49
03DC864E87EBA3C1EE594FAACAFE93CA6F3410D847AC0C0ACB9FD88EC9CF6B00379FA9AD256C86
7204ED81E3FA2F8F492109FF87E81398B7B489B00A35914A2B51919DAAEC2BA87CEFB5AF52294E
2448B5B150D50A39BA0471A9AA1EA2B38A4E23BBA56E029842459F0D5BA3D511

Zertifikatbeispiel Beispiel

10
nixspirit
package test.pkcs7;

import Java.io.ByteArrayOutputStream;
import Java.io.FileInputStream;
import Java.math.BigInteger;
import Java.security.KeyStore;
import Java.security.PrivateKey;
import Java.security.Signature;
import Java.security.cert.X509Certificate;
import Java.util.Enumeration;

import Sun.security.pkcs.ContentInfo;
import Sun.security.pkcs.PKCS7;
import Sun.security.pkcs.SignerInfo;
import Sun.security.util.DerOutputStream;
import Sun.security.util.DerValue;
import Sun.security.x509.AlgorithmId;
import Sun.security.x509.X500Name;

public class GenPKCS {

    static final String STORENAME = "c:/fileName.p12";
    static final String STOREPASS = "password";

    public static void main(String[] args) throws Exception{

        //First load the keystore object by providing the p12 file path
        KeyStore clientStore = KeyStore.getInstance("PKCS12");
        //replace testPass with the p12 password/pin
        clientStore.load(new FileInputStream(STORENAME), STOREPASS.toCharArray());

        Enumeration<String> aliases = clientStore.aliases();
        String aliaz = "";
        while(aliases.hasMoreElements()){
            aliaz = aliases.nextElement();
            if(clientStore.isKeyEntry(aliaz)){
                break;
            }
        }
        X509Certificate c = (X509Certificate)clientStore.getCertificate(aliaz);

        //Data to sign
        byte[] dataToSign = "SigmaWorld".getBytes();
        //compute signature:
        Signature signature = Signature.getInstance("Sha1WithRSA");
        signature.initSign((PrivateKey)clientStore.getKey(aliaz, STOREPASS.toCharArray()));
        signature.update(dataToSign);
        byte[] signedData = signature.sign();

        //load X500Name
        X500Name xName      = X500Name.asX500Name(c.getSubjectX500Principal());
        //load serial number
        BigInteger serial   = c.getSerialNumber();
        //laod digest algorithm
        AlgorithmId digestAlgorithmId = new AlgorithmId(AlgorithmId.SHA_oid);
        //load signing algorithm
        AlgorithmId signAlgorithmId = new AlgorithmId(AlgorithmId.RSAEncryption_oid);

        //Create SignerInfo:
        SignerInfo sInfo = new SignerInfo(xName, serial, digestAlgorithmId, signAlgorithmId, signedData);
        //Create ContentInfo:
        ContentInfo cInfo = new ContentInfo(ContentInfo.DIGESTED_DATA_OID, new DerValue(DerValue.tag_OctetString, dataToSign));
        //Create PKCS7 Signed data
        PKCS7 p7 = new PKCS7(new AlgorithmId[] { digestAlgorithmId }, cInfo,
                new Java.security.cert.X509Certificate[] { c },
                new SignerInfo[] { sInfo });
        //Write PKCS7 to bYteArray
        ByteArrayOutputStream bOut = new DerOutputStream();
        p7.encodeSignedData(bOut);
        byte[] encodedPKCS7 = bOut.toByteArray();
    }
}

Die folgenden Änderungen müssen im Code Java) vorgenommen werden, damit die Ausgabe .NET ähnelt:

//Create ContentInfo:
ContentInfo cInfo = new ContentInfo(ContentInfo.DIGESTED_DATA_OID, new DerValue(DerValue.tag_OctetString, dataToSign));

ändern

//Create ContentInfo:
ContentInfo cInfo = new ContentInfo(ContentInfo.DATA_OID, new DerValue(DerValue.tag_OctetString, dataToSign));
9
Mohit Sethi