CMS/PKCS#7メッセージ(C# SignedCms に似たもの)の署名とエンコードに取り組んでいます。
キーストアからのx509certificate、rsa秘密鍵、
ContentInfo。 ContentTypeは「oidPkcs7Data」です。
次に何をしたらいいのかよくわかりません。
私は思った:
Signature signature = Signature.getInstance( "MD5withRSA"); signature.initSign(rsaPrivateKeyFromStore); signature.update(contentInfo.getData()); signedData = signature.sign();
PKCS7 pkcs7 = new PKCS7(signedData); ByteArrayOutputStream baos = new ByteArrayOutputStream(); pkcs7.encodeSignedData(baos);
しかし、私は例外を得ました
Sun.security.pkcs.ParsingException:エンコードされたバイトを解析できません Sun.security.pkcs.PKCS7。(PKCS7.Java:94)
明らかに私はそれを間違っています。
また、これらのようなBouncyCastleやClasspthやsmthなしでそれを実行したいと思います。
Sun.security。*クラスだけを使用することはできますか?私はJava 1.5を使用しています。
私はDigitalSignatureの世界で新しいです。どんな助けやアドバイスもありがたいです。
UPD
私は自分の証明書を生成し、それでデータに署名しようとしました。
.Netコード
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コード
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出力
length=264
3082010406092A864886F70D010702A081F63081F3020101310B300906052B0E03021A0500
301306092A864886F70D0 -> 10705A <- 0060404746578743181CB3081C8020101302630123110300E06
035504031307436F6D70616E790210FCAF9B5224FB4B9F4000B5127D881E2E300906052B0E0302
1A0500300D06092A864886F70D0101010500048180636ADD9F7E218AF3CBC5A75FA2076A53BE49
03DC864E87EBA3C1EE594FAACAFE93CA6F3410D847AC0C0ACB9FD88EC9CF6B00379FA9AD256C86
7204ED81E3FA2F8F492109FF87E81398B7B489B00A35914A2B51919DAAEC2BA87CEFB5AF52294E
2448B5B150D50A39BA0471A9AA1EA2B38A4E23BBA56E029842459F0D5BA3D511
.Net出力
length=264
3082010406092A864886F70D010702A081F63081F3020101310B300906052B0E03021A0500
301306092A864886F70D0 -> 10701A <- 0060404746578743181CB3081C8020101302630123110300E06
035504031307436F6D70616E790210FCAF9B5224FB4B9F4000B5127D881E2E300906052B0E0302
1A0500300D06092A864886F70D0101010500048180636ADD9F7E218AF3CBC5A75FA2076A53BE49
03DC864E87EBA3C1EE594FAACAFE93CA6F3410D847AC0C0ACB9FD88EC9CF6B00379FA9AD256C86
7204ED81E3FA2F8F492109FF87E81398B7B489B00A35914A2B51919DAAEC2BA87CEFB5AF52294E
2448B5B150D50A39BA0471A9AA1EA2B38A4E23BBA56E029842459F0D5BA3D511
証明書の例 example
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();
}
}
Javaコードで次の変更を行って、出力を.NETのようにします。
//Create ContentInfo:
ContentInfo cInfo = new ContentInfo(ContentInfo.DIGESTED_DATA_OID, new DerValue(DerValue.tag_OctetString, dataToSign));
への変更
//Create ContentInfo:
ContentInfo cInfo = new ContentInfo(ContentInfo.DATA_OID, new DerValue(DerValue.tag_OctetString, dataToSign));