Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用OpenSSL验证用Java签名的文件_Java_C++_Openssl_Dsa_Java Security - Fatal编程技术网

使用OpenSSL验证用Java签名的文件

使用OpenSSL验证用Java签名的文件,java,c++,openssl,dsa,java-security,Java,C++,Openssl,Dsa,Java Security,我用Java创建的签名无法用OpenSSL验证。如果有任何提示,我将不胜感激 以下是我所做的: 1) 使用Java密钥工具生成密钥对: >> keytool -genkeypair -alias signing_test -keyalg DSA -keysize 2048 -keypass test123 -dname 'CN=tilo, OU=dev, O=company, L=SF, ST=CA, C=US' -keystore test_store.jks -s

我用Java创建的签名无法用OpenSSL验证。如果有任何提示,我将不胜感激

以下是我所做的:

1) 使用Java密钥工具生成密钥对:

>> keytool -genkeypair -alias signing_test -keyalg DSA -keysize 2048 -keypass test123 
   -dname 'CN=tilo, OU=dev, O=company, L=SF, ST=CA, C=US' 
   -keystore test_store.jks -storepass test123
>> keytool -exportcert -alias signing_test -keypass test123 -keystore test_store.jks 
   -storepass test123 -rfc -file public_key.pem
2) 使用Java对文件进行签名:

import java.io.*;
import java.nio.file.*;
import java.security.*;

public class SignatureTest {
  public static void main(String[] args) throws Exception {
    String path = "..."; // Local Path
    String keyStoreFile = path + "test_store.jks";
    String dataFile = path + "picture.jpg";
    String signatureFile = path + "signature.data";

    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    try (FileInputStream inputStream = new FileInputStream(keyStoreFile)) {
      keyStore.load(inputStream, "test123".toCharArray());
    }

    Signature sig = Signature.getInstance("SHA256withDSA"); // requires Java 8
    sig.initSign((PrivateKey)keyStore.getKey("signing_test", "test123".toCharArray()));
    byte[] data = Files.readAllBytes(Paths.get(dataFile));
    sig.update(data);
    Files.write(Paths.get(signatureFile), sig.sign());  
  }
}
3) 使用Java密钥工具导出证书:

>> keytool -genkeypair -alias signing_test -keyalg DSA -keysize 2048 -keypass test123 
   -dname 'CN=tilo, OU=dev, O=company, L=SF, ST=CA, C=US' 
   -keystore test_store.jks -storepass test123
>> keytool -exportcert -alias signing_test -keypass test123 -keystore test_store.jks 
   -storepass test123 -rfc -file public_key.pem
4) 使用OpenSSL验证签名:

#include <fstream>
#include <string>
#include <vector>
#include <stdio.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/err.h>

void ReadData(const std::string& fileName, std::vector<unsigned char>& data) {
  std::ifstream inFile{ fileName.c_str(), 
         std::ios::in | std::ios::binary | std::ios::ate };
  auto size = inFile.tellg();
  data.resize(size);
  inFile.seekg(0, std::ios::beg);
  inFile.read(reinterpret_cast<char*>(data.data()), size);
  inFile.close();
}

int main(int argc, char** argv) {
  std::string path = "..."; // Local Path
  std::string publicKeyFileName = path + "public_key.pem";
  std::string dataFileName = path + "picture.jpg";
  std::string signatureFileName = path + "signature.data";

  // Read certificate
  FILE *publicKeyFile = fopen(publicKeyFileName.c_str(), "rb");
  X509 *x509 = PEM_read_X509(publicKeyFile, nullptr, nullptr, nullptr);
  fclose(publicKeyFile);

  // Read signature & data
  std::vector<unsigned char> data;
  ReadData(dataFileName, data);
  std::vector<unsigned char> sig;
  ReadData(signatureFileName, sig);

  // Verify
  EVP_PKEY *publicKey = X509_get_pubkey(x509);

  EVP_MD_CTX messageDigest;
  EVP_MD_CTX_init(&messageDigest);

  EVP_VerifyInit(&messageDigest, EVP_sha256());
  EVP_VerifyUpdate(&messageDigest, data.data(), data.size());
  int result = EVP_VerifyFinal(&messageDigest, sig.data(), sig.size(), publicKey);

  if (result > 0) {
    std::cout << "Verifed\n";
  } else if (result == 0) {
    std::cout << "Failure\n";
  } else {
    ERR_print_errors_fp(stderr);
  }

  // Cleanup
  EVP_MD_CTX_cleanup(&messageDigest);
  EVP_PKEY_free(publicKey);
  X509_free(x509);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
void ReadData(const std::string和fileName,std::vector和data){
std::ifstream infle{fileName.c_str(),
std::ios::in | std::ios::binary | std::ios::ate};
自动大小=infle.tellg();
数据。调整大小(大小);
填充seekg(0,标准::ios::beg);
infle.read(重新解释投射(data.data()),大小);
infle.close();
}
int main(int argc,字符**argv){
std::string path=“…”;//本地路径
std::string publicKeyFileName=path+“public_key.pem”;
std::string dataFileName=path+“picture.jpg”;
std::string signatureFileName=path+“signature.data”;
//阅读证书
FILE*publicKeyFile=fopen(publicKeyFileName.c_str(),“rb”);
X509*X509=PEM_read_X509(publicKeyFile,nullptr,nullptr,nullptr);
fclose(publicKeyFile);
//读取签名和数据
std::矢量数据;
ReadData(数据文件名、数据);
std::载体sig;
读取数据(signatureFileName,sig);
//核实
EVP_PKEY*publicKey=X509_get_publicKey(X509);
执行副总裁MD CTX信息摘要;
EVP_MD_CTX_init(&messageDigest);
EVP_VerifyInit(&messageDigest,EVP_sha256());
EVP_VerifyUpdate(&messageDigest,data.data(),data.size());
int result=EVP_VerifyFinal(&messageDigest,sig.data(),sig.size(),publicKey);
如果(结果>0){

std::你是在Windows上运行吗?你应该用
“rb”
而不是
“r”
@kichik打开文件谢谢你抓到了!是的,我是在Windows上运行的。所以它仍然失败?结果的值是多少?在调用
EVP\U VerifyFinal()之前没有错误检查
所以从技术上讲,它可以是那个调用之上的任何东西。@kichik是的,它仍然失败。从调试中我可以看出,公钥加载很好。我还检查了所有适用的
EVP_xxx
调用的返回码,但从问题中删除了它,使其更短。您的代码在带有Java SE 1.8.0_73和OpenSS的OS X上对我有效L 1.0.2f.我还能够在命令行上使用OpenSSL进行验证,使用
OpenSSL x509-pubkey-noout-in public_key.pem>foo.pem
OpenSSL dgst-sha256-verify foo.pem-signature signature.data picture.jpg
。这可能有助于将您的问题隔离到一个程序中。