RSA通过USB-token + C#签名并由Java验证

时间:2015-07-08 08:05:37

标签: java c# cryptography rsa signature

我尝试验证服务器端的RSA签名,该签名是通过USB-token和.Net在客户端上签名的。

所以,我有:

公钥
模量

zpF/kA34TKgsx1G2arEwceaKf1gzEsV3gHPtzmABimmrb2hlVDmcix2Pt554U+LHD/okgnNesSwww8FGCaQBmw==
指数

AQAB

源数据

29062015

签名base64

77+9zqYT77+9d8WL77+977+92JXvv73Zqe+/vVfvv73vv73vv71SYB9b77+9BXob77+9DO+/veqGn++/ve+/vVXSqtWdRixlSyDvv70iVe+/vQ8x77+977+977+977+9bFF+77+9Nw==

我的Java代码验证:

public static void test() {
    String modB64 = "zpF/kA34TKgsx1G2arEwceaKf1gzEsV3gHPtzmABimmrb2hlVDmcix2Pt554U+LHD/okgnNesSwww8FGCaQBmw==";
    String expB64 = "AQAB";

    String phrase = "29062015";
    String sign = "77+9zqYT77+9d8WL77+977+92JXvv73Zqe+/vVfvv73vv73vv71SYB9b77+9BXob77+9DO+/veqGn++/ve+/vVXSqtWdRixlSyDvv70iVe+/vQ8x77+977+977+977+9bFF+77+9Nw==";

    PublicKey pubKey = constructPublicKey(modB64, expB64);
    Log.m("ver: " + verify(pubKey, phrase.getBytes("UTF-8"), b64decode(sign)));
}


private static PublicKey constructPublicKey(String modB64, String expB64) 
                throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, UnsupportedEncodingException {
    BigInteger mod = new BigInteger(b64decode(modB64));
    BigInteger exp = new BigInteger(b64decode(expB64));
    RSAPublicKeySpec keySpec = new RSAPublicKeySpec(mod, exp);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
    PublicKey key = keyFactory.generatePublic(keySpec);
    return key;
}

private static boolean verify(
        PublicKey publicKey, byte[] message, byte[] signature)
        throws SignatureException, NoSuchAlgorithmException,
        UnsupportedEncodingException, InvalidKeyException,
        NoSuchProviderException {
    Signature sign = Signature.getInstance("SHA1withRSA", "BC");
    sign.initVerify(publicKey);
    sign.update(message);
    return sign.verify(signature);
}

private static final byte[] b64decode(String data)
        throws UnsupportedEncodingException {
    return Base64.getDecoder().decode(data.getBytes("UTF-8"));
}

但它总是返回假 此外,我尝试使用另一种编码(ASCII,windows-1251)与 getBytes()方法,这不解决问题。
我也尝试在没有BouncyCatle的情况下进行验证。

但是签名和密钥对必须是正确的,我猜,因为我用C#测试它并且这个工作正常:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
RSAParameters prsa = new RSAParameters();
prsa.Modulus = Convert.FromBase64String("zpF/kA34TKgsx1G2arEwceaKf1gzEsV3gHPtzmABimmrb2hlVDmcix2Pt554U+LHD/okgnNesSwww8FGCaQBmw==");
prsa.Exponent = Convert.FromBase64String("AQAB");
rsa.ImportParameters(prsa);

string data = "29062015";
string sign64 = "77+9zqYT77+9d8WL77+977+92JXvv73Zqe+/vVfvv73vv73vv71SYB9b77+9BXob77+9DO+/veqGn++/ve+/vVXSqtWdRixlSyDvv70iVe+/vQ8x77+977+977+977+9bFF+77+9Nw==";

byte[] dtBuffer = Encoding.Default.GetBytes(data);
byte[] sgBuffer = Convert.FromBase64String(sign64);

if (rsa.VerifyData(dtBuffer, CryptoConfig.MapNameToOID("SHA1"), sgBuffer))
   result.Text += "\nRight!";

请帮帮我 Java方面有什么问题?为什么我可以通过C#验证此签名,但是不能通过Java验证?

0 个答案:

没有答案