Pergunta

Eu estou olhando para converter algum código C # para o equivalente em Java.

O código C # leva algum conteúdo corda, e uma assinatura (gerado usando a chave privada, em uma máquina separada) e combinado com a chave pública que verifica as partidas de assinatura, proporcionando um nível de garantia de que o pedido não foi adulterado com.

  public bool VerifySignature(string content, byte[] signatureBytes, AsymmetricAlgorithm publicKey)
  {
        var hash = new MD5CryptoServiceProvider();

        byte[] dataBuffer = Encoding.ASCII.GetBytes(content);

        var cs = new CryptoStream(Stream.Null, hash, CryptoStreamMode.Write);
        cs.Write(dataBuffer, 0, dataBuffer.Length);
        cs.Close();

        var deformatter = new RSAPKCS1SignatureDeformatter(publicKey);
        deformatter.SetHashAlgorithm("MD5");

        return deformatter.VerifySignature(hash, signatureBytes);
  }

A chave pública em si é um certificado X509 -. Construído a partir de um arquivo .cer, armazenado como conjunto de recursos ou seja

byte[] data; // data is read from a resource stream.
var publicKey = new X509Certificate2(data, "", X509KeyStorageFlags.MachineKeySet).PublicKey.Key

O que eu estou procurando fazer é imitar essa funcionalidade em Java, para que eu possa verificar a assinatura gerada por algum código em C # ... Eu já começou a investigar a funcionalidade de criptografia de Java, mas eu sou um pouco de um java do noob. Aqui está o que eu vim acima com até agora:

byte[] certContents=null;
byte[] signature=null;
String contents = "abc";

// load cert
CertificateFactory factory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(certContents));

// grab public key
RSAPublicKey publicKey = (RSAPublicKey)cert.getPublicKey();

// get sha1 hash for contents        
Mac mac = Mac.getInstance("HmacSHA1");
mac.update(contents.getBytes());                
byte[] hash = mac.doFinal();

// get cipher
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);

// verify signature of contents matches signature passed to method somehow (and this is where I'm stuck)

Alguém pode fornecer qualquer visão sobre como eu posso verificar a assinatura -. Ou fornecer links para alguns recursos que poderia explicar o uso java.crypto e java.security.cert melhor, então o prazo dos docs moinho java

Foi útil?

Solução

Esse código C # parece realmente confuso para mim. Ele usa SHA1CryptoServiceProvider mas usa hash MD5, então não posso dizer qual algoritmo de hash que ele está usando. Eu supor que é MD5.

A assinatura verificação processo envolve preenchimento para que o seu código não iria funcionar. Após algum trecho do meu código e você pode usá-lo para verificar a assinatura. dados é o bytes para assinar e sigBytes detém a assinatura.

String algorithm = "MD5withRSA";

// Initialize JCE provider    
Signature verifier = Signature.getInstance(algorithm);

// Do the verification   
boolean result=false;

try {
    verifier.initVerify(cert); // This one checks key usage in the cert
    verifier.update(data);
    result = verifier.verify(sigBytes);
}
catch (Exception e) {
    throw new VerificationException("Verification error: "+e, e);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top