Beruflich Dokumente
Kultur Dokumente
Master 2 E-Secure
Introduction : .............................................................................................................................. 3
1. Présentation du sujet, état de l’art : .................................................................................... 4
1.1. Sujet du projet : .......................................................................................................... 4
1.2. Standard existant : ...................................................................................................... 4
1.3. Vue d’ensemble de la signature et vérification par XML Dsig : ............................... 5
1.4. Solutions existantes :.................................................................................................. 6
1.5. Solution retenue : ....................................................................................................... 6
2. Signature d’un document ................................................................................................... 7
2.1. Les trois formes de signature : ................................................................................... 7
2.2. Forger une signature en respectant XML Dsig : ........................................................ 8
2.3. Canonisation............................................................................................................. 10
2.4. Programmation de l’action de signature................................................................... 12
2.5. Résultat : signature d’un document XML ................................................................ 13
3. Vérification d’un document signé .................................................................................... 14
3.1. Vérifier une signature selon XML Dsig ................................................................... 14
3.2. Programmation de l’action de vérification............................................................... 15
4. Gestion des certificats ...................................................................................................... 16
4.1. Utilisation du Keystore / Truststore ......................................................................... 16
4.2. Génération du keystore et du truststore :.................................................................. 17
4.3. Validation d’un certificat : ....................................................................................... 17
5. Réalisation d’un prototype et tests ................................................................................... 19
5.1. Prototypage avec le framework Play........................................................................ 19
5.2. Tests ......................................................................................................................... 20
6. Evolutions possibles......................................................................................................... 20
6.1. Amélioration de la gestion des certificats ................................................................ 20
6.2. Complément à la canonisation : ............................................................................... 21
7. Conclusion........................................................................................................................ 21
8. Annexes : Annexe 1: Code Java de signe.class ............................................................. 22
Annexe 2: Code Java de valide.class ................................................................................... 25
Annexe 3: Code Java de TestCert.class ............................................................................... 28
Annexe 4: Lignes de commandes Keytool........................................................................... 31
Annexe 5: HTTPS configuration for play framework.......................................................... 32
Introduction
Le langage XML (eXtended Markup Langage) a été promu en version 1.0 par W3C
en 1998. Il s’ajoute à la famille des langages à balises (GML,HTML…). Les
possibilités de définition infinie d’objets l’ont rendu très populaire et XML est devenu
un standard universel pour la représentation et l’échange de données.
- Intégrité
On est capable de savoir si les données reçues ont été modifiées.
- Non re-jeu
La signature est propre au document. Elle n’est pas valide pour d’autres
usages.
J’ai choisi ce sujet dans un but d’apprentissage. Ne connaissant pas le langage XML
et n’ayant pas développé en langage objet, j’ai trouvé en ce projet une bonne
opportunité pour enrichir mes connaissances.
Enfin, le sujet devrait me permettre d’appliquer les outils de cryptographie abordés
en cours.
1. Présentation du sujet, état de l’art :
1.1. Sujet du projet :
La signature de document numérique utilisant des principes de cryptographie
asymétrique est un processus bien connu. Ces schémas considèrent généralement
le document comme une simple suite d'octets non structurée de taille quelconque et
produisent à l'aide de la clé secrète du signataire, une signature de quelques
centaines d'octets. Cette dernière doit être adjointe au document. On pourra ensuite
prouver son intégrité et son origine à l'aide d'une procédure de vérification utilisant la
clé publique du signataire.
Le problème est ici de signer des documents XML dont il est licite de modifier leur
présentation sans pour autant constituer un autre document XML au sens de la
norme. En effet, l'ordre d'écriture des sous éléments de même nom d'un élément ou
l'ordre d'apparition des attributs d'un élément dans sa balise ouvrante ne sont pas
significatifs. Il faut donc que la signature ne soit pas dépendante de ces ordres. Nous
souhaitons aussi pouvoir ajouter cette signature au document. De plus comme nous
voulons appliquer ce schéma à de « petits » documents, il faudra expérimenter des
schémas à bas coûts.
<dossier medical>
<patient>
pat ient
...
</patient>
m edecin
<medecin>
...
</medecin>
Radiologue
<radio>
Scanner ...
</radio>
.....
pharm acien .....
.....
.....
laborat oire .....
d'analyse
</dossier medical>
Des exemples de codes Java sont également fournis pour générer la signature et
la valider. Je me suis appuyé sur ces exemples que j’ai pu compléter.
2. Signature d’un document
2.3. Canonisation
Les algorithmes d’empreintes cryptographiques utilisés pour générer une signature
considèrent les données à signer au niveau binaire. Le moindre changement
entraîne un résultat complètement différent.
2
http://www.w3.org/TR/xml-c14n
La canonisation c14n effectue principalement ces transformations :
Toutefois, c14n ne répond pas complètement à nos besoins. En effet, les opérations
de tri réalisées ne sont pas suffisantes. Le tri est effectué sur les attributs dans une
balise ouvrante est réalisé et vérifié. Par contre, le tri des éléments de mêmes noms
n’est pas réalisé. Il faudra donc ajouter une transformation complémentaire
consistant à effectuer ce tri en complément à c14n.
2.4. Programmation de l’action de signature
L’action Signature est remplie par la classe Signe.class (voir Annexe).
Les principales étapes de cette fonction sont décrites ci-dessous (la gestion des
exceptions n’est pas renseignée ici pour en alléger la représentation ; les
fonctions intégrées par la bibliothèque réalisent plusieurs opérations induites).
Ref : Reference
Ref si : SignedInfo
kp ki : KeyInfo
signat ure
signed
fichier XML
Ecrit ure dans fichier XML
Fig. 6 : signe.class
2.5. Résultat : signature d’un document XML
• Vérifier la référence :
• Valider la signature :
Fig. 8 : valide.class
4. Gestion des certificats
Java permet de stocker des clés, paires de clés ou certificats dans des Keystore.
Ces entrées sont associées à un alias afin d’en faciliter la gestion pour les ranger,
utiliser, supprimer.
Signataire Recepteur
XML signé
Certificats importé
dans le trustore
(Kpriv1,Cert1) Cert1
(Kpriv2,Cert2) Cert3
.... ...
(Kpriv-n,Cert_n) Cert_i
KEYSTORE Liste de TRUSTSTORE ....
révocation (Kpriv-n,Cert_n)
Pour la signature :
• Le signataire récupère sa paire de clés dans le keystore.
• Le chiffrement est réalisé avec sa clé privée.
• Son certificat est joint dans l’élément signature.
Pour la vérification :
• Le destinataire valide le certificat du signataire en consultant le
truststore et la liste de révocation.
• Dans le cas où le certificat est valide, le destinataire peut vérifier la
signature en utilisant la clé publique contenue dans le certificat.
4.2. Génération du keystore et du truststore :
Les principaux logiciels libres pour générer les paires de clés et certificats sont
OpenSSL et Keytool.
Keytool permet également l’interfaçage avec les keystore. Cela se fait en trois
étapes :
• Générer un Keystore Java et une paire de clef
• Exporter un certificat autosigné à partir de la clé publique
• Importer un certificat dans un truststore
Lignes de commandes et détails fournies dans l’Annexe 4.
La vue correspond à une page web en langage http dont le rendu est le suivant :
Pour les deux premiers cas, la signature remplit son rôle. Les altérations de données
ou la valeur de signature sont détectées : la vérification indique que la signature n’est
pas correcte.
A noter que la signature d’un même fichier réalisé plusieurs fois donnera une valeur
de signature différente dues à un aléa ajouté dans l’algorithme de chiffrement de
celle-ci. La vérification à l’aide de la clé publique commune correspondant confirme
que toutes ces valeurs sont correctes.
Enfin, les quatre derniers tests montrent l’efficacité de la canonisation c14n sauf dans
les cas d’apparition dans différents ordres des nœuds éléments. Il est nécessité de
compléter par une transformation de type tri d’éléments.
6. Evolutions possibles
7. Conclusion
L’objectif du projet est partiellement atteint. En effet, la signature et la vérification
fonctionnent. La réalisation d’un prototype via une page web est également
disponible et sera présenté lors de la soutenance. Toutefois, la transformation
consistant au tri des éléments (complément à la canonisation standard) n’a pas été
codée. Suite à la présentation à mi-parcours, j’ai préféré concentrer mon travail pour
inclure la couche de sécurisation d’échanges de données par l’utilisation de
certificats.
J’estime mon temps passé sur ce projet à un peu plus de soixante-dix heures. Mes
difficultés ont essentiellement résidé dans la programmation pour laquelle j’ai
consommé plus de 30% du temps.
J’ai développé mes connaissances concernant le langage XML. Partant de zéro, cela
m’a paru simple de premier abord. Mais, de sorte à comprendre les transformations
opérées par la canonisation standard, il m’a fallu aller plus loin et d’avantage
comprendre des principes qui en font la richesse.
J’ai également découvert ce qu’offre Java pour le développement. Les bibliothèques
contiennent l’essentiel des composants nécessaires pour répondre aux besoins :
génération et vérification de signature, gestion des clés cryptographiques.
Mon travail a consisté pour l’essentiel à rechercher, comprendre et adapter ces
briques. D’avantage de temps m’aurait été nécessaire pour mieux maîtriser ce
langage et améliorer mon efficacité.
8. Annexes :
/**
* signatureEnveloppe ouvre le fichier XML à signer, effectue sa canonisation,
* signe le fichier et créé un nouveau fichier signé
* NOTE a compléter avec transformation pour le tri d'éléments
*/
public static Document signatureEnveloppe(Document doc){
String fichierKeystore ="D:\\DATA\\DEVELOPPEMENT\\JAVA\\Essais\\keystore.jks";
String ks_keypair ="selfsigned";
try {
//Creation d'une factory signature
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
Collections.singletonList(fac.newTransform(Transform.ENVELOPED,
(TransformParameterSpec) null)),
null, null);
//Collections.singletonList(fac.newTransform(Transform.ENVELOPED,
(TransformParameterSpec) null)),
//Collections.singletonList(fac.newTransform(CanonicalizationMethod.EXCLUSIVE_WITH_CO
MMENTS,
// (C14NMethodParameterSpec) null))
//définition du noeud SignedInfo
SignedInfo si =
fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE_WITH_CO
MMENTS,
(C14NMethodParameterSpec)
null),fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null),Collections.singletonList(ref));
//Creation du noeud KeyInfo contenant le certificat
//Chargement du KeyStore, Extraction de la clé priv et du certificat
char[] password1 = "pwd_ks".toCharArray();
char[] password2 = "pwd_kpriv".toCharArray();
KeyStore kstore = KeyStore.getInstance("JKS");
kstore.load(new FileInputStream(fichierKeystore), password1);
KeyPair kpair = getKeyPair(kstore, ks_keypair, password2);
//Signature du Document
signature.sign(dsc);
return doc;
} catch(Exception e){
e.printStackTrace();
}
return null;
}
/**
*Creation d'un Document à partir d'un fichier XML
*/
public static Document LectureXML(String FileInput){
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(new FileInputStream(FileInput));
return doc;
}catch(Exception e){
e.printStackTrace();
}
return null;
}
/**
*Creation d'un fichier XML à partir d'un document
*/
public static void EcritureXML(Document doc,String FileOutput){
try {
OutputStream os;
if (FileOutput.length() !=0) {
os = new FileOutputStream(FileOutput);
} else {
os = System.out;
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));
}catch(Exception e){
e.printStackTrace();
}
}
}
Annexe 2: Code Java de valide.class
public class Validate {
//
// Synopsis: java Validate [document]
//
// where "document" is the name of a file containing the XML document
// to be validated.
//
public static void main(String[] args) throws Exception {
//Import du certificat
CertificateFactory cf = CertificateFactory.getInstance("X509");
// Certificate myCert2=cf.generateCertificate(
// // string encoded with default charset
// new ByteArrayInputStream(certString.getBytes())
// );
FileInputStream in = new
FileInputStream("D:\\DATA\\DEVELOPPEMENT\\JAVA\\Essais\\mydomain.crt");
Certificate myCert = cf.generateCertificate(in);
//Validation du certificat
valCert=TestCert(doc)
//Validation de la signature
boolean valsig = signature.validate(valContext);
}
}
Annexe 3: Code Java de TestCert.class
//--- Valide le certificat contenu dans le document XML en se basant sur le truststore ----
//Import du Certificat
NodeList nl1 = doc.getElementsByTagName("X509Certificate");
if (nl1.getLength() == 0) {
throw new Exception("Certificat X509 non trouvé");
}
String certPart = nl1.item(0).getFirstChild().getNodeValue();
System.out.println(certPart);
InputStream is = new ByteArrayInputStream(certPart.getBytes());
// debug...
// voir http://www.sauronsoftware.it/projects/javabase64/manual.php
FileOutputStream fout = new
FileOutputStream("D:\\DATA\\DEVELOPPEMENT\\JAVA\\Essais\\mydomain2.crt");
try (ObjectOutputStream oos = new ObjectOutputStream(fout)) {
oos.writeObject(is);
}
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
//Validité du certificat
try{
cert.checkValidity();
}
catch(CertificateExpiredException | CertificateNotYetValidException e){
System.out.println("Certificat non valide :"+ e.toString());
System.exit(0) ;
}
try
{
//------ récupération du nom lié au certificat ------------------
// InputStream inStream = new FileInputStream(CERTFILE);
// CertificateFactory cf = CertificateFactory.getInstance("X.509");
// X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
// inStream.close();
String issuerdn = cert.getIssuerDN().getName() ;
// System.out.println("\nIssuerName:\r\n" + issuerdn) ;
Enumeration en = keystore.aliases();
String ALIAS = "" ;
if(! verCert)
System.out.println("Certificat non valide");
}
catch (Exception e)
{
System.err.println("Caught exception " + e.toString());
}
}
Annexe 4: Lignes de commandes Keytool
The built-in server supports the HTTPS protocol, which you can use it in production.
It supports certificate management, either via the classical Java keystore or simple
cert and key files. To start an HTTPS connector for your application, just declare the
https.port configuration property in your application.conf file:
http.port=9000
https.port=9443
You need to put your certificates in the conf directory. Play supports X509 certificates
and keystore certificates. The X509 certificates must be named as follows:
host.cert for the certificate and host.key for the key. If you are using keystore, then,
by default it should be named certificate.jks.
If you are using X509 certificates, then the following parameters can be configured in
your application.conf file:
# X509 certificates
certificate.key.file=conf/host.key
certificate.file=conf/host.cert
# In case your key file is password protected
certificate.password=secret
trustmanager.algorithm=JKS
keystore.algorithm=JKS
keystore.password=secret
keystore.file=conf/certificate.jks
If you are using the Java keystore mechanism, then the following properties can be
configured in your application.conf file:
# Keystore
ssl.KeyManagerFactory.algorithm=SunX509
trustmanager.algorithm=JKS
keystore.password=secret
keystore.file=certificate.jks