代码之家  ›  专栏  ›  技术社区  ›  Questioner

JAVA中的签名验证与签名长度

  •  2
  • Questioner  · 技术社区  · 7 年前

    我开发了一个java应用程序,如下所示,它从PEM文件中读取公钥,然后验证签名。我从外部(一家公司)收到此签名,它是使用RSA2048生成的。但是,我收到以下错误消息:

    “签名长度不正确:获得384,但预期为256。”

    在验证之前,我必须对这个签名做一些修改吗?

     package read_key_pck;
    
    import static java.nio.charset.StandardCharsets.UTF_8;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.security.KeyFactory;
    import java.security.NoSuchAlgorithmException;
    import java.security.NoSuchProviderException;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.Security;
    import java.security.Signature;
    import java.security.spec.InvalidKeySpecException;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Base64;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    
    public class Main {
    
        //protected final static Logger LOGGER = Logger.getLogger(Main.class);
    
        public final static String RESOURCES_DIR = "C:\\Users\\KX5710\\eclipse-workspace\\read_key\\src\\read_key_pck\\";
    
        public static boolean verify(String plainText, String signature, PublicKey publicKey) throws Exception {
            Signature publicSignature = Signature.getInstance("SHA256withRSA");
            publicSignature.initVerify(publicKey);
            publicSignature.update(plainText.getBytes(UTF_8));
    
            byte[] signatureBytes = Base64.getDecoder().decode(signature);
    
            return publicSignature.verify(signatureBytes);
        }
    
        public static void main(String[] args) throws Exception {
            Security.addProvider(new BouncyCastleProvider());
    
            PublicKey pub = null;
            KeyFactory factory = KeyFactory.getInstance("RSA", "BC");
            try {
                /*PrivateKey priv = generatePrivateKey(factory, RESOURCES_DIR
                        + "id_rsa");*/
    
    
                pub = generatePublicKey(factory, RESOURCES_DIR
                        + "rsa_2048_pub.pem");
    
            } catch (InvalidKeySpecException e) {
                e.printStackTrace();
            }
            String encodedPublicKey = Base64.getEncoder().encodeToString(pub.getEncoded());
            System.out.println("publickey: " + encodedPublicKey);
    
            boolean isCorrect = verify("         5   5.00   1.80", "12c1d454cde1c3ca07f179fc3c8d1e739b482b0447cd2c60342455a10db15ee8657e73e7f9195f7e33d93db8fc1cda236d41bf2a804be0f860c16ebf952c02e89f254a19daf54b66d1383ebe5aaf049e7c48ecd33a98f771165cb8b7b0323d81508c6260109c8f622655f363bbf638802d92c985e8ab982eebc7167c979cde4755b7afcc880e32118c3e6b72eecbd0ebf680da84a59c8cc523051c3a8ec12595ec6bdc0856b9faf9562919c315e78655c8f35f759899f27d729e56a96ec8bd85fe6221441dd91f9facd5f5eadcb4b7fac08a9ddab29f18d353e6762e0769068077fea7bc94d6df405a86c9e98096e8e50e59ec7263ce6c4e88bb96ab3c663baa", pub);
            System.out.println("Signature verification: " + isCorrect);
        }
    
        private static PublicKey generatePublicKey(KeyFactory factory,
                String filename) throws InvalidKeySpecException,
                FileNotFoundException, IOException {
            PemFile pemFile = new PemFile(filename);
            byte[] content = pemFile.getPemObject().getContent();
            X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
            return factory.generatePublic(pubKeySpec);
        }
    }
    
    
    package read_key_pck;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import org.bouncycastle.util.io.pem.PemObject;
    import org.bouncycastle.util.io.pem.PemReader;
    
    public class PemFile {
    
        private PemObject pemObject;
    
        public PemFile(String filename) throws FileNotFoundException, IOException {
            PemReader pemReader = new PemReader(new InputStreamReader(
                    new FileInputStream(filename)));
            try {
                this.pemObject = pemReader.readPemObject();
            } finally {
                pemReader.close();
            }
        }
    
        public PemObject getPemObject() {
            return pemObject;
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   pedrofb    7 年前

    您的签名编码为十六进制,而不是BASE64。 改变

    byte[] signatureBytes = Base64.getDecoder().decode(signature); 
    

    具有

    byte[] signatureBytes = DatatypeConverter.parseHexBinary(signature)