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

无法验证签名ECDSA密钥

终洛华
2023-03-14

我试图使用javascript创建ECDSA算法的密钥对,签名消息,然后在服务器端验证它(使用Java)。

示例javascript代码:

    // help function
    function _arrayBufferToBase64( buffer ) {
        var binary = '';
        var bytes = new Uint8Array( buffer );
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
            binary += String.fromCharCode( bytes[ i ] );
        }
        return window.btoa( binary );
    }
    const encodedMessage = new TextEncoder().encode('test');

    // keys generation
    crypto.subtle.generateKey({
        name: 'ECDSA',
        namedCurve: 'P-256'
    }, true, ['sign','verify']).then((keys) => {

        console.log('keys:', keys);
        console.log('[....] public key export');

        // public key export
        crypto.subtle.exportKey('spki', keys.publicKey).then(result => {

            console.log('publicKey byte:', result);
            console.log('publicKey base64:', _arrayBufferToBase64(result));
  
            // sign
            crypto.subtle.sign({
                    name: 'ECDSA',
                    hash: {name:'SHA-256'}
                },
                keys.privateKey,
                encodedMessage
                ).then(signature => {

                    console.log('signature byte:', signature);
                    console.log('signature base64:', _arrayBufferToBase64(signature));
          
                    // verify
                    crypto.subtle.verify({
                            name: 'ECDSA',
                            hash: {name: 'SHA-256'}
                        },
                        keys.publicKey,
                        signature,
                        encodedMessage
                    ).then(verified => {
                         console.log('signature verified?', verified);
                    });
                });
         });
     });

例如:


    publicKey base64: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERhn3GM1eQodijVDdy0Zb+ERjvWZ6idQw8PbaFfTzPdA7oNFh8+AHlni91snTS5Sk2o4Xw9CCnlvHP3uWVyCIvA==
    signature base64: nAHPhibM3txezQ53O3C4vMlbQnMI75ILcaamqBezNS51c6wB2ZHwwk/4phgbp+aFlM9omvxaH0fdzJpCT0s/Zg==
    signature verified? true

private boolean receiver(String message, String algorithm, String signature, String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, UnsupportedEncodingException, SignatureException {

    Signature ecdsaVerify = Signature.getInstance(algorithm);

    //import org.apache.commons.codec.binary.Base64;
    byte[] decodedPk = Base64.decodeBase64(new String(publicKey).getBytes("UTF-8"));
    EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(decodedPk);

    KeyFactory keyFactory = KeyFactory.getInstance("EC");
    PublicKey pk = keyFactory.generatePublic(publicKeySpec);
    
    ecdsaVerify.initVerify(pk);
    
    byte[] decodedString = new String(message).getBytes("UTF-8");
    byte[] decodedSignature = Base64.decodeBase64(new String(signature).getBytes("UTF-8"));

    ecdsaVerify.update(decodedString);
    boolean result = ecdsaVerify.verify(decodedSignature);

    return result;
}

    String message = "test";
    String algorithm = "SHA256withECDSA";
    String signature = "nAHPhibM3txezQ53O3C4vMlbQnMI75ILcaamqBezNS51c6wB2ZHwwk/4phgbp+aFlM9omvxaH0fdzJpCT0s/Zg==";
    String publicKey = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERhn3GM1eQodijVDdy0Zb+ERjvWZ6idQw8PbaFfTzPdA7oNFh8+AHlni91snTS5Sk2o4Xw9CCnlvHP3uWVyCIvA==";


    [err] java.security.SignatureException: Could not verify signature
    [err]   at sun.security.ec.ECDSASignature.engineVerify(ECDSASignature.java:325)
    [err]   at java.security.Signature$Delegate.engineVerify(Signature.java:1223)
    [err]   at java.security.Signature.verify(Signature.java:656)
    [err]   at it.bpc.bpwebrs.application.services.IamService.receiver(IamService.java:2740)
    [err]   at it.bpc.bpwebrs.application.services.IamService.elaboraAbilitazioni(IamService.java:186)
    [err]   at it.bpc.bpwebrs.infrastructure.servicesImpl.IamResource.eseguiServizioElaborazione(IamResource.java:127)
    [err]   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    [err]   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    [err]   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    [err]   at java.lang.reflect.Method.invoke(Method.java:498)
    [err]   at it.bpc.bpwebrs.dispatcher.DispatcherResource.richiamaServizioRichiesto(DispatcherResource.java:447)
    [err]   at it.bpc.bpwebrs.dispatcher.DispatcherResource.postJSONRequest(DispatcherResource.java:227)
    [err]   at sun.reflect.GeneratedMethodAccessor77.invoke(Unknown Source)
    [err]   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    [err]   at java.lang.reflect.Method.invoke(Method.java:498)
    [err]   at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
    [err]   at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
    [err]   at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
    [err]   at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160)
    [err]   at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
    [err]   at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
    [err]   at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
    [err]   at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
    [err]   at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
    [err]   at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    [err]   at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    [err]   at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    [err]   at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    [err]   at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    [err]   at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    [err]   at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
    [err]   at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
    [err]   at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
    [err]   at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
    [err]   at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
    [err]   at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
    [err]   at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
    [err]   at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1285)
    [err]   at [internal classes]
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    [err]   at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    [err]   at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    [err]   at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    [err]   at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    [err]   at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    [err]   at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    [err]   at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    [err]   at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:155)
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    [err]   at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    [err]   at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:176)
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    [err]   at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    [err]   at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    [err]   at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    [err]   at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    [err]   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    [err]   at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    [err]   at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    [err]   at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    [err]   at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
    [err]   at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
    [err]   at [internal classes]
    [err]   at it.bpc.bpwebrs.infrastructure.security.cors.CorsFilter.doFilter(CorsFilter.java:180)
    [err]   at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
    [err]   at [internal classes]
    [err]   at it.bpc.bpwebrs.infrastructure.filters.MDCFilter.doFilter(MDCFilter.java:49)
    [err]   at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
    [err]   at [internal classes]
    [err]   at it.bpc.bpwebrs.utilities.infrastructure.EncodingFilter.doFilter(EncodingFilter.java:30)
    [err]   at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
    [err]   at [internal classes]
    [err]   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    [err]   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    [err]   at java.lang.Thread.run(Thread.java:748)
    [err] Caused by: java.security.SignatureException: Invalid encoding for signature
    [err]   at sun.security.ec.ECDSASignature.decodeSignature(ECDSASignature.java:400)
    [err]   at sun.security.ec.ECDSASignature.engineVerify(ECDSASignature.java:322)
    [err]   ... 92 more
    [err] Caused by: java.io.IOException: Sequence tag error
    [err]   at sun.security.util.DerInputStream.getSequence(DerInputStream.java:330)
    [err]   at sun.security.ec.ECDSASignature.decodeSignature(ECDSASignature.java:376)
    [err]   

... 93 more

我做错了什么?

共有1个答案

越源
2023-03-14

ECDSA签名有不同的格式,一方面是IEEE P1363(rs)格式,另一方面是ASN.1/DER编码。

这里解释了两种格式之间的关系。

WebCrypto应用IEEE P1363格式,Java代码中的网站和SHA256WithECDSA算法使用ASN.1/DER。

import org.bouncycastle.jce.provider.BouncyCastleProvider;
...
Security.addProvider(new BouncyCastleProvider());
Signature ecdsaVerify = Signature.getInstance("SHA256withPlain-ECDSA", "BC"); //IEEE P1363
 类似资料:
  • 我正在尝试在python中使用ECDSA验证比特币签名,但发现它非常困难,许多尝试已经失败了。 参数: 注意:我已经根据ECDSA的要求将签名从base64转换为hexstring。每当我试图验证它时,它会说: 预期64字节签名(128十六进制字符串),提供了65字节签名(130十六进制字符串) 我查看了许多关于ECDSA的stackoverflow问题,但没有一个答案与我的qs 100%相关。感

  • 我传入以下内容(摘要/哈希是SHA1): 到此功能: 但我无法在OpenSSL中验证签名(verify_success为0),即使完全相同的数据在C#中验证成功。 关于我为什么或做错了什么的任何想法? C#中的公钥是: 我假设4543533120000000是。NET特定的东西,所以我只是把04前置到它的其余部分。 这是用于验证签名的C#代码,它成功地做到了(dataBytes的SHA1在两个程序

  • 我想创建一个签名并使用openssl验证它。我想有我的签名的十六进制输出。 这是我的密码 我得到这个错误: 如果我在创建签名的过程中删除了-hex,它就可以工作了。

  • 我应该如何更改A方法?任何想法都是好的。提前谢谢。

  • 最近,我一直在尝试构建一个Java库来解释和验证NZ Covid传递。在签名验证之前(这个过程中稍微重要的一部分),我已经让代码变得更好或更坏。完整的代码可以在这里找到,但是仍然很粗糙。 验证器本身在这里可用,有一个配套测试。新冠通行证的技术规范在这里。至少有一个相关部分。 在与另一个开发人员合作后,我想我已经确定了解释提供的公钥。下面的代码(删除了调试输出)。公钥详细信息来自这里 该错误可能存在

  • 我在应用程序中用戴伟的加密技术创建了一个ECDSA密钥对(secp128r1)。签名和验证按预期工作。我没有将消息本身添加到签名中,以最小化签名长度(正好是32个字节)。 但是,当我使用openssl创建签名时: 显然,OpenSSL将消息本身放在签名中,导致更大的签名(例如39字节)。如果我设置< code > CryptoPP::SignatureVerificationFilter::PUT