Resums, signatures i certificats

Resums de missatges

Els resums s'implementen utilitzant la classe java.security.MessageDigest, que permet generar un resum de dades. El resum es pot fer segur utilitzant javax.crypto.Mac. També es pot realitzar l'operació amb Streams gràcies a java.security.DigestInputStream i java.security.DigestOutputStream.

Alguns algorismes típics de resums: MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512.

MessageDigest messageDigest = MessageDigest.getInstance(algorithm); byte[] resum = messageDigest.digest(text.getBytes());

Resums segurs

Un Message Authentication Code (javax.crypto.Mac) és un resum xifrat amb una clau secreta compartida. Només es pot verificar si tens aquesta clau. Podem generar-lo així:

Mac mac = Mac.getInstance(algorithm); mac.init(key); // la clau secreta byte[] macBytes = mac.doFinal(text.getBytes());

Un algorisme podria ser HmacSHA256 (HMAC: Hash-based MAC).

Key Derivation Functions

Amb una KDF, podem generar una clau més llarga que un passowrd, per exemple. Aquí tenim un exemple utilitzant l'algorisme PBKDF2WithHmacSHA256.

SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); KeySpec ks = new PBEKeySpec(password, salt, iterationCount, keyLength); SecretKey rawSecret = f.generateSecret(ks); // secret genèric SecretKey aesSecret = new SecretKeySpec(s.getEncoded(), "AES"); // secret AES

Els paràmetres del KeySpec són:

  • password: un char[] amb la contrasenya.
  • salt: una salt per a randomitzar el hash.
  • iterationCount: nombre d'iteracions per a generar el hash.
  • keyLength: longitud de la clau a generar.

Signatures digitals

Una signatura digital equival a fer un resum i xifrar-lo amb una clau privada. El receptor podria desxifrar-lo amb la pública, i comparar-lo amb un resum que faci de les dades (en pla) rebudes.

Els algorismes són variats, per exemple, SHA256withRSA indica que el resum es fa amb SHA256 i el xifratge amb RSA. Per tant, les claus utilitzades han de ser RSA. Per a signar una entrada (array de bytes):

Signature sign = Signature.getInstance(algorithm); sign.initSign(privateKey); sign.update(input); byte[] signatura = sign.sign();

Per verificar-la:

Signature sign = Signature.getInstance(algorithm); sign.initVerify(publicKey); sign.update(input); boolean correcte = sign.verify(signatura);

Certificats

Els certificats (java.security.cert.Certificate) més habituals són de tipus X.509, i indiquen una vinculació d'una identitat a una clau pública, garantida per una altra entitat autoritzada. Inclouen:

  • data d'inici i fi
  • versió (3 actualment)
  • número de sèrie (únic per proveïdor)
  • el DN (distinguished name) de la CA emissora
  • el DN del subjecte del certificat

Els DN (Distinguished Names) conté una sèrie de camps (CN, OU, O, L, S, C) que identifiquen tant l'emissor com el subjecte.

Habitualment, els trobem dins dels magatzems. Per gestionar-los podem utilitzar l'eina keytool del JRE o bé programàticament amb la classe java.security.KeyStore i els mètodes getKey(alias) (clau privada) i getCertificate(alias) (certificat on hi la clau pública).

Són necessaris als portals web amb seguretat habilitada HTTPS.