it-swarm-tr.com

PKCS7 kodlaması Java BouncyCastle vb. Gibi harici kütüphaneler olmadan

İmzalama ve CMS/PKCS # 7 mesajlarını (C # SignedCms ) benzer bir şey kodlama üzerinde çalışıyorum.

Anahtar deposundan x509c sertifikam var, rsa özel anahtarı,
ContentInfo. ContentType "oidPkcs7Data" dır.

Bundan sonra ne yapmam gerektiğini tam olarak anlamıyorum.

Düşündüm:

  1. imza oluşturma ve ContentInfo verilerini imzalama
 İmza signature = Signature.getInstance ("MD5withRSA"); 
 Signature.initSign (rsaPrivateKeyFromStore); 
 signature.update (contentInfo.getData ()); 
 İmzalıData = signature.sign (); 
  1. kodlama imzalanmışVeri + imzası.
 PKCS7 pkcs7 = yeni PKCS7 (işaretliVeri); 
 ByteArrayOutputStream baos = yeni ByteArrayOutputStream (); [.____. Pkcs7.encodeSignedData (baos); [.____]

Ama istisnayım

 Sun.security.pkcs.ParsingException: Kodlanan baytlar 
 Sun.security.pkcs.PKCS7. (PKCS7.Java:94) 
 'Da ayrıştırılamıyor

Açıkçası yanlış yapıyorum.

Ayrıca bu gibi BouncyCastle veya Classpth veya smth olmadan yapmak istiyorum.

Yalnızca Sun.security. * Sınıflarını kullanmak mümkün müdür? Java 1.5 kullanıyorum.

DigitalSignature dünyasında yeniyim ve herhangi bir yardım veya tavsiye takdir ediliyor.

UPD

Kendi sertifikamı oluşturdum ve verileri onunla imzalamaya çalıştım.

Net kodu

        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 kodu

    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 çıktısı

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

Net çıkışı

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

Sertifika örneği örnek

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

Çıktı .NET'e benzer hale getirmek için Java kodunda aşağıdaki değişiklikler yapılmalıdır:

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

değişmek

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