我有一个Java代码,通过它我可以生成一个已签名的内容,并可以使用此符号内容发送获取数据的请求。现在,我想将此Java代码转换为php,这意味着我想使用php对内容进行签名。
我使用Java keytool创建了证书KeyStore.jks文件。
使用此Java代码生成符号。
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.Base64;
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.JcaSimpleSignerInfoGeneratorBuilder;
import org.bouncycastle.util.Store;
//import sun.misc.BASE64Encoder;
public class GenerateSignature {
private static final char JKSPassword[];
private static final char PFXPassword[];
private static KeyStore ks = null;
private static String alias = null;
private static X509Certificate UserCert = null;
private static PrivateKey UserCertPrivKey = null;
private static PublicKey UserCertPubKey = null;
private static X509Certificate myPubCert = null;
static {
JKSPassword = "nopassword".toCharArray();
PFXPassword = "tcs".toCharArray();
}
public GenerateSignature() {
}
public static void main(String[] args) {
String aspId = "XA5P4RD1823D000785";
String ts = "";
ts = getCurrTs();
System.out.println("AspId : " + aspId);
System.out.println("TimeStamp : " + ts);
String aspData = aspId + ts;
try {
String sign = generateSignature(aspData);
System.out.println("sign:" + sign);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String generateSignature(String data) throws Exception {
System.out.println("@@inside generateSignature: " + data);
String signature;
String jksFilepath = "C:\\KeyStore.jks";
try {
// Adding Security Provider for PKCS 12
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
// Setting password for the e-Token
// logging into token
ks = KeyStore.getInstance("jks");
FileInputStream fileInputStream = new FileInputStream(jksFilepath);
// Loading Keystore
// System.out.println("loading keystore");
ks.load(fileInputStream, JKSPassword);
Enumeration<String> e = ks.aliases();
while (e.hasMoreElements()) {
alias = e.nextElement();
// System.out.println("Alias of the e-Token : "+ alias);
UserCert = (X509Certificate) ks.getCertificate(alias);
UserCertPubKey = (PublicKey) ks.getCertificate(alias).getPublicKey();
// System.out.println("loading Private key");
UserCertPrivKey = (PrivateKey) ks.getKey(alias, JKSPassword);
}
// Method Call to generate Signature
signature = MakeSignature(data);
return signature;
} catch (Exception e) {
e.printStackTrace();
System.out.println("generateSignature" + e.getCause());
throw new Exception();
}
}
private static String MakeSignature(String data) {
System.out.println("@@inside MakeSignature...");
try {
PrivateKey privateKey = (PrivateKey) ks.getKey(alias, JKSPassword);
System.out.println(privateKey.getEncoded().toString());
myPubCert = (X509Certificate) ks.getCertificate(alias);
Store certs = new JcaCertStore(Arrays.asList(myPubCert));
CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
generator.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").build("SHA256withRSA", privateKey, myPubCert));
generator.addCertificates(certs);
CMSTypedData data1 = new CMSProcessableByteArray(data.getBytes());
CMSSignedData signed = generator.generate(data1, true);
//BASE64Encoder encoder = new BASE64Encoder();
//String signedContent = encoder.encode((byte[]) signed.getSignedContent().getContent());
//String envelopedData = encoder.encode(signed.getEncoded());
String envelopedData = Base64.getEncoder().encodeToString(signed.getEncoded());
return envelopedData;
} catch (Exception e) {
e.printStackTrace();
System.out.println("MakeSignature ==" + e.getCause());
return "";
}
}
public static String getCurrTs() {
System.out.println("@@inside getCurrTs...");
Calendar cal = Calendar.getInstance();
SimpleDateFormat format1 = new SimpleDateFormat("ddMMyyyyHHmmssSSS111");
String tmpstmp = format1.format(cal.getTime());
return tmpstmp;
}
}
这使我的输出为
MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwGggCSABCYyN0FMQ1BEMTkzMUEwMDAyNTAwMjAzMjAxOTE2MDgzMzc5NjExMQAAAAAAAKCAMIIDzTCCArWgAwIBAgIEUdU8GjANBgkqhkiG9w0BAQsFADCBljELMAkGA1UEBhMCSU4xFDASBgNVBAgTC01haGFyYXNodHJhMQ8wDQYDVQQHEwZNdW1iYWkxMTAvBgNVBAoTKE5TREwgZS1Hb3Zlcm5hbmNlIEluZnJhc3RydWN0dXJlIExpbWl0ZWQxFTATBgNVBAsTDGUtR292ZXJuYW5jZTEWMBQGA1UEAxMNZU5QUy5uc2RsLmNvbTAeFw0xOTAyMjExMTAyMTFaFw0xOTA1MjIxMTAyMTFaMIGWMQswCQYDVQQGEwJJTjEUMBIGA1UECBMLTWFoYXJhc2h0cmExDzANBgNVBAcTBk11bWJhaTExMC8GA1UEChMoTlNETCBlLUdvdmVybmFuY2UgSW5mcmFzdHJ1Y3R1cmUgTGltaXRlZDEVMBMGA1UECxMMZS1Hb3Zlcm5hbmNlMRYwFAYDVQQDEw1lTlBTLm5zZGwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgwJWlIbe1Lr43dOxvOrs3XZmGGCJHxfgnJCnIgWfWCS2zJFwkjNliDagmRKy86MuLtNuQv2cwIYGyATLUjkElt / kQGe8erpXGPb6Iqv2NNY7mPj3GdUTrnofse2FVUvrdt1WtqYYQ3ldBnDfWGYxadmzjSgtkOSl2ozFl8fuYstqye08XSovvY5fsGi + JS9RhW65WtvkL / TEQaezutgdJe / p3lc5eQB09fwhgbDRo4eusy8iigap3yR67rNFkPafACwalm0u0T8jojo + 1auM9JXL2waUsDgJmROyUOSG9EXhbday27UsK + OO3 + FWD / RRC j7PNSERsnRV8IqVf40vnQIDAQABoyEwHzAdBgNVHQ4EFgQU3Qqp9L1zyptxSv4lLFcQgXFBN4owDQYJKoZIhvcNAQELBQADggEBAECqBuB48sJdaflo6EVEpGXdpt8bv9qCHIIrUBnfas + FOsy6ag / njH2K1NNV8iy3oPh5cTQiUf22KliW2pYRMELN0bC32XNHnmHZPFzbcGhhkvj39lF3Y4l9Z8MT9boueFV3u3s8dETb99fmbiwT3uSrdbJix + lmFJNoHr0Gq / SWxcVmdO7Qbk0yEHUbqNNXxf1U / ozCXC4PtlAfPIfFZ7LFXp7YwboXrZlObkC2rsEWyvAojUJ8FVhxyRBhu7pHIdqKXdCwFeiSfGJKrx9lNhhmlunBSGdWAgydKzlREx + Hfw0nycy98PfFh3Cz1tUtARL5w / Y + yjgdijmlP5qqBaQAADGCAmYwggJiAgEBMIGfMIGWMQswCQYDVQQGEwJJTjEUMBIGA1UECBMLTWFoYXJhc2h0cmExDzANBgNVBAcTBk11bWJhaTExMC8GA1UEChMoTlNETCBlLUdvdmVybmFuY2UgSW5mcmFzdHJ1Y3R1cmUgTGltaXRlZDEVMBMGA1UECxMMZS1Hb3Zlcm5hbmNlMRYwFAYDVQQDEw1lTlBTLm5zZGwuY29tAgRR1TwaMA0GCWCGSAFlAwQCAQUAoIGYMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE5MDMwMjEwMzgzNFowLQYJKoZIhvcNAQk0MSAwHjANBglghkgBZQMEAgEFAKENBgkqhkiG9w0BAQsFADAvBgkqhkiG9w0BCQQxIgQgCuw9nea7vZG33erYzeUSQhPNwHjRys97c2rQfZDeNp4wDQYJKoZIhvcNAQELBQAEggEABaMrzBX23vkmZxEHHxPmyupJknO + 5sJDnqSDx1MzRilcy0hg8K + d + / E75P8 / lZ31oa / He4G3T C703ghOgiRIwsaSgaS2Yg5mkKn9GlVzCPosVKRnODLjGwj + C / ofZjK7M0KeFK0Lf6YVF6fxsTE1UwGOKbZ1kKYOq + 6fPxvDnfPVhuKSvjRJJ9UHws7TBeEZWFCRzI1ud1nOqCg7lvMe / DjnypOSN2td6oAE2opubOR8KPCmh9XoTb0R2lJ9cYFdEdzvB4n5Q8aTvYz2dQvVOv7q8jkrntLW8lK + OV + LrVVqp + Cx8HtfKrt6NLUJ2i302SuawItC7SsEXH4AhiUX0AAAAAAAAA ==
现在这可以正常工作。我想要一个可以为我做的PHP代码。我的意思是,PHP没有选择从 JKS文件获取内容的选项,因此我将 jks文件转换为pfx 。使用命令。
keytool -importkeystore -srckeystore KeyStore.jks -destkeystore mynewPfx.pfx -srcstoretype JKS -d eststoretype PKCS12 -deststorepass xxxxxx -srcalias域-destalias域-keysize 2040
这给了我 pfx 文件。现在要对内容进行签名,我在php代码中使用openssl。
<?php date_default_timezone_set("Asia/Kolkata");
//data you want to sign
$date=date('dmYHisnnnnnn');
$aspid="XA5P4RD1823D000785";
$data = $aspid.$date;
$cert_store = file_get_contents("mynewPfx.pfx");
openssl_pkcs12_read($cert_store, $cert_info, "nopassword");
//var_dump($cert_info);
//create signature
openssl_sign($data, $signature, $cert_info['pkey'], "sha256WithRSAEncryption");
//finally encode
$r = base64_encode($signature);
echo '<br>';
print "sign: ".$r;
?>
这给了我类似的签名内容。
KiadpEipXMbvGQq5YJvMKfvGnm + 3czL40IXMR8GQM1XTheHsbhoTVbUpkGWh6yOMBUGg4FtWlucX2tpZfTC + Pin8DBqrUzxd3PBuFoyx7a / BHRVL / E8iq / 7yGM / s0fT3GqH68SmGSgiP84 + Pfnje4s + 46d1Q6wZds2Pr9LWdmuE3XrzMl + x8D6xfXf / SDSQHUs77V9NQ1nH9w7va9XuNdGCjJQIoA9iIaJUdQJdvwbwrtK5shnUWKJg2A9xKPgJsH0zqjdijTXog6 + kC2ghDlFli5vrgBluDj483ykcU / HNqDhfOkGdcBZ8H6x5VjD2oyhskyiAM0iDW02WgGVH6BA ==
php给了我签名内容,但这是不同的。这意味着它与java输出不匹配。以及长度也要小。任何人都有任何选择。为此。