Pregunta

Estoy buscando para convertir algo de código C # para el equivalente en Java.

El código C # toma algún contenido de la cadena, y una firma (generado utilizando la clave privada, en una máquina independiente) y se combina con la clave pública se verifica coincide con la firma, proporcionando un nivel de seguridad de que la solicitud no ha sido manipulado con.

  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);
  }

La propia clave pública es un certificado X509 - construido a partir de un archivo .cer, es decir almacenan como recursos de montaje

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

Lo que estoy buscando que hacer es emular esta funcionalidad en Java, para que pueda verificar la firma generada por algún código en C # ... He empezado a investigar la funcionalidad criptográfica de Java, pero estoy un poco de un novato java. Esto es lo que he encontrado hasta el momento:

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)

Puede alguien dar alguna idea de cómo puedo comprobar la firma -. O proporcionar enlaces a algunos recursos que podría explicar el uso java.crypto y java.security.cert mejor que la ejecución de los documentos molino de Java

¿Fue útil?

Solución

Ese código C # se ve muy confuso para mí. Utiliza SHA1CryptoServiceProvider pero utiliza hash MD5 así que no puedo decir qué algoritmo de hash que está usando. Asumo que es MD5.

El proceso de verificación de la firma consiste en el relleno para que su código no funcionaría. Lo que sigue es un poco fragmento de mi código y se puede utilizar para verificar la firma. datos son los bytes a firmar y sigBytes sostiene la firma.

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top