当前位置: 首页 > 知识库问答 >
问题:

在C#中创建的数字签名在Java验证中不匹配

龚威
2023-03-14
        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

        RSA.FromXmlString(privateKey);

        var encoder = new UTF8Encoding();
        byte[] originalData = encoder.GetBytes(message);
        SHA1 sha1 = SHA1.Create();

        byte[] signedBytes = RSA.SignData(originalData, sha1);

        return signedBytes;
   //read xml file to get modulus and exponent bytes
            File publicKeyFileQA = new File(PUBLIC_KEY_FILE_QA);

            Map<String, BigInteger> publicKeyModulusExponentValues = DSXCRM_3YBP_Global_WebServicesUtil.readXMLFile(publicKeyFileQA);

            BigInteger publicKeyModulus = publicKeyModulusExponentValues.get("modulus");
            BigInteger publicKeyExponent = publicKeyModulusExponentValues.get("exponent");

            System.out.println("BigInteger Modulus : "+ publicKeyModulus + "BigInteger Exponent : " + publicKeyExponent);

            String messageWithSignature = (String) mapDataToPost.get("SignedMessage");
            String encryptedMessage = (String) mapDataToPost.get("EncryptedMessage");

            byte[] signatureBytes = DatatypeConverter.parseBase64Binary(messageWithSignature);

            System.out.println("Signature bytes : "+ new String(signatureBytes));


            byte[] cipherMessage = DatatypeConverter.parseBase64Binary(encryptedMessage);

            System.out.println("Cipher Message : "+ new String(cipherMessage));

            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(publicKeyModulus, publicKeyExponent);
            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
            Signature sig = Signature.getInstance("SHA1withRSA");
            sig.initVerify(publicKey); //public key of sender
            sig.update(cipherMessage);

            boolean isRightSender = sig.verify(signatureBytes);
            System.out.println("isRightSender : "+isRightSender);

共有1个答案

冯鸿光
2023-03-14

您正在读取一个名为“SignedMessage”的字段,将其存储在一个名为“MessageWithSignature”的变量中,然后将其视为签名。Blob中实际存在哪些数据?

您还可以像打印文本一样打印二进制数据(通过new String(byte[]))。对于消息字节(在验证器中似乎称为ciphermessage)和签名,您应该双面打印Base64或hex,以查看它们是否匹配。

如果切换到静态数据(以避免在读取时计算换行符之类的事情),那么这样做应该是有效的

byte[] originalData = Encoding.UTF8.GetBytes("This is a static message test.");
Console.WriteLine(Convert.ToBase64String(rsa.SignData(originalData), "SHA1"));

然后获取该输出,将其放入Java程序并验证

byte[] originalData = "This is a static message test.".getBytes("UTF-8");
byte[] signature = Base64.getDecoder().decode(theOutputFromTheCSharpProgram);
Signature verifier = new Signature("SHA1withRSA");
verifier.initVerify(publicKey);
verifier.update(originalData);
System.out.println(verifier.verify(signature));

如果该部分不起作用,那么您一定不能忠实地在两边表示相同的键。

RSA签名的二进制格式在C#和Java中是相同的;因此,一旦你得到了良好的数据传输,一切都应该工作。

 类似资料:
  • 情况是我必须检查一个数字签名: 字符串1“A1005056807CE11EE2B4CE0025305725CFRCN=KED,OU=I0020266601,OU=SAPWebAS,O=SAPTrustCommunity,C=DE20130611102236”通过PKCS#7签名并通过HTTP-URL发送给我。 我在BASE64中获得签名的内容(在代码字符串sc中查找)。 现在我必须检查,如果Str

  • 我正在用C#开发一个执行数字签名验证的webserver,以确保pdf文件没有被修改。我使用了iText和iTextSharp。 和我的C#验证码: 在VerifySignature(name)行中;抛出NullReferenceException! 有趣的是,如果我使用C#代码执行签名,我就可以在java中验证它,因为我添加了这些指令:BouncyCastleProvider provider=

  • 我正在用Java对一个二进制文件进行签名。我能够在Java代码中签名和验证,但是在openssl中使用生成的签名时,它无法验证到相同的二进制文件。步骤是:加载数据- 这应该相当于在openssl: openssl dgst-sha256-符号private.key-二进制target.bin 我验证了sha256与openssl生成的匹配。

  • 最近我需要在Java中使用RSA对一个字符串进行签名,并在C++中验证签名。 在Java,现在我认为一切都是好的,我创建了public.keystore和private.keysore,可以成功地对数据进行签名和veify。但是当我试图用C++验证它时,它显示签名失败。 这是我的Java代码,在Java,我将数据签名到base64String,并将其保存在我的本地文件中,保存为“sig.dat”,

  • 我有一个使用C++中的openSSL生成的keypair,我正在使用它在一个严格使用RSACryptoServiceProvider(没有BouncyCastle等)的C#服务器上对验证消息进行签名。我使用PKCS#1 SHA256生成签名,然后以十六进制的形式与公钥一起传输签名。问题是无法在服务器上验证签名。我已经尝试删除了头,上面写着“----开始RSA公钥-----”等等。但是还没有结果。生

  • 我在看正式的PDF规范。我在这里看到一个数字签名的PDF文件。当我在分析它的目录词典时,我看到了这样的: 数字签名采用签名字段的形式,该字段指定签名所应用的内容的字节范围。添加在上面的任何内容,如注释、注释等,都应该以增量更新的方式进入,因此原始内容的有效性应该继续保持正确(不包括直接编辑内容,如将示例单词更改为示例2)。但是,当我在Nitro中打开文件,在其中添加一些高亮或注释,保存并在Acro