Crittografia a Chiave Simmetrica e Asimmetrica
Procollo SSL: breve introduzione
Cifrare una request SOAP con BinarySecurityToken
Importare il jar wss4j versione 2.2.1 (ultima versione al momento)
<dependency>
<groupId>org.apache.wss4j</groupId>
<artifactId>wss4j-bindings</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.wss4j</groupId>
<artifactId>wss4j-integration</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.wss4j</groupId>
<artifactId>wss4j-ws-security-common</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.wss4j</groupId>
<artifactId>wss4j-ws-security-dom</artifactId>
<version>2.1.1</version>
</dependency>
Creare un Handle:
WSSUsernameTokenSecurityHandler .java
package it;
import java.io.FileInputStream;
import java.io.StringWriter;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.crypto.CryptoFactory;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.message.WSSecHeader;
import org.apache.wss4j.dom.message.WSSecSignature;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
public class WSSUsernameTokenSecurityHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public Set<QName> getHeaders() {
final QName securityHeader = new QName(
“http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”,
“Security”,
“wsse”);
final HashSet<QName> headers = new HashSet<QName>();
headers.add(securityHeader);
return headers;
}
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
SOAPMessage message = smc.getMessage();
if (outboundProperty) {
try {
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header2 = envelope.addHeader();
Source source = soapPart.getContent();
Node root = null;
Document doc = null;
if (source instanceof DOMSource) {
root = ((DOMSource) source).getNode();
}
else if (source instanceof SAXSource) {
InputSource inSource = ((SAXSource) source).getInputSource();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = null;
db = dbf.newDocumentBuilder();
doc = db.parse(inSource);
root = (Node) doc.getDocumentElement();
}
org.apache.wss4j.dom.message.WSSecSignature builderSig = new WSSecSignature();
builderSig.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
org.apache.wss4j.dom.message.WSSecHeader secHeader = new WSSecHeader();
secHeader.insertSecurityHeader(header2.getOwnerDocument());
Properties config = new Properties();
config.load(new FileInputStream(“merlin.properties”)) ;
Crypto crypto = CryptoFactory.getInstance(config);
//dobbiamo capire perche la seguente serve, invece di prendere dal properties
builderSig.setUserInfo(“<Nome Alias>”,”<Password>”);
builderSig.setUseSingleCertificate(true);
secHeader.setMustUnderstand(false);
secHeader.getSecurityHeader().removeAttribute(“S:mustUnderstand”);
builderSig.appendBSTElementToHeader(secHeader);
builderSig.build((Document)root, crypto, secHeader);
printNode((Document)root);
}
catch (Exception ex) {
ex.printStackTrace();
System.exit(-1);
}
}
return true;
}
public boolean handleFault(SOAPMessageContext smc) {
// addDigitalSignature(smc);
return true;
}
// nothing to clean up
public void close(MessageContext messageContext) {
}
}
Di seguito il file di merlin.properties:
org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlin
org.apache.wss4j.crypto.merlin.keystore.type=jks
org.apache.wss4j.crypto.merlin.keystore.password=<Password>
org.apache.wss4j.crypto.merlin.keystore.alias=<Nome Alias>
org.apache.wss4j.crypto.merlin.keystore.file=<Nome File>.jks
l xml prodotto avrà un header così composto:
<soapenv:Header>
<wsse:Security
xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”
xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd”>
<wsse:BinarySecurityToken
EncodingType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary”
ValueType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3″
wsu:Id=”X509-C672A11E5F8017AFA114337688056892″>MIIDWjCCAkICCQCzH8uW6SulfzANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTESMBAGA1UECAwJS3Jvbm9iZXJnMQ4wDAYDVQQHDAVWYXhqbzERMA8GA1UECgwIR1RFQ0ggRzIxDjAMBgNVBAsMBUlUIERDMRkwFwYDVQQDDBBzdGFnZS1zcG4tZ21zLTAyMB4XDTExMTIxNTE1MDkyMVoXDTIxMTIxMjE1MDkyMVowbzELMAkGA1UEBhMCU0UxEjAQBgNVBAgMCUtyb25vYmVyZzEOMAwGA1UEBwwFVmF4am8xETAPBgNVBAoMCEdURUNIIEcyMQ4wDAYDVQQLDAVJVCBEQzEZMBcGA1UEAwwQc3RhZ2Utc3BuLWdtcy0wMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM5qyhAUFE4lY8rLfGqT1ZjhC4DGTCt8++eBK9xN+Li2cGbqHJBghl1U/6LgHR8/KDYDf0dWKXp89eVIYDpxRhIJgdnFnRbk2/I7Vbq67pyTSkk6DgdyyS55EhKr8Zzb8Eh9dTJsUyWLR9FVEfxHP19ghtW6swLcrH2e+Ktd0OvR0GcOEnalx1VvGLLftyT98ppnhg6YGoyA+uQkri/82COyzbkCyRtbtXB4jq4vEMgv9dTv1l6IXQpSXRncZ3t8SGOL9m6SoHjERsSrhnS4tq6ZffkgBjgfJa2oT4qWO8KeF3yqA8Bmwyzv+v2Ow5mfj6VXcLKzUA+MG4hQ7uZ8SCkCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAbnRcqaQZXxYSn8XEzqmA5L4+ESzhugaiyMWb0n0sklC3AJOufw4gCeK++3GLhqYmhHGmt0T0P3nrcRY6w8SkPsM/Zo0tKdA+W3SrEhDxOi/nhxJoosVcxmk2Qzg9zlKrBMbCic+5OBhkqpUMXTQcl4eOgfIAEtXt8rcaARMLcFx6EWjGc37tejE3nyjtjbGYgLV0RqEsTKz/+qkRx3DZZt441ewH32p+wM6GEexYlVa9lhPi53gB5uxjXzuNGQqqacfI8da+e2JGKavb44DCGraRvUKMxGrO6uGOHoZOvxYXw8J9FVrZ4pr5D3ec7WmNPfgWMkJKjMfM5F2gh8jnkA==</wsse:BinarySecurityToken>
<ds:Signature Id=”SIG-C672A11E5F8017AFA114337688058496″
xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”>
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm=”http://www.w3.org/2001/10/xml-exc-c14n#”>
<ec:InclusiveNamespaces PrefixList=”soapenv ver”
xmlns:ec=”http://www.w3.org/2001/10/xml-exc-c14n#” />
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm=”http://www.w3.org/2000/09/xmldsig#rsa-sha1″ />
<ds:Reference URI=”#id-C672A11E5F8017AFA114337688058355″>
<ds:Transforms>
<ds:Transform Algorithm=”http://www.w3.org/2001/10/xml-exc-c14n#”>
<ec:InclusiveNamespaces PrefixList=”ver”
xmlns:ec=”http://www.w3.org/2001/10/xml-exc-c14n#” />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm=”http://www.w3.org/2000/09/xmldsig#sha1″ />
<ds:DigestValue>ZrNB9LZb2Eu9pr0rWKg1V2p5ehc=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>GVD3r4yb38OtFPb4PgnnTpOfl60VymGr18/pAsn5hrAZUUMcuCuIPLwV+0cfIoiCTSbRohvEJojW
IXAepaIf/OqfZSsBipHTe2ExFCA36uhnwUO0LC13k+DyvpUmOn2y1g0BIg/RZkwqRy+JktThIAsq
VgTa1AYyQeKY79GG2Pcla+X7iufj2Q9BBidQkK+czNsBSUW8LdSJdq3/+4QJZscODR9c+ybOG1yO
6EyLRU36Tnw3kA2ftzve+hCtxVHeQSh+LcrD1DI4L0uwrhlpwE9ai2mOrSBNLa2q1k1TmnRzAsgv
EqdCkPImL9pySVKPB/uM0sL37Cblfn0Y9JXlkQ==
</ds:SignatureValue>
<ds:KeyInfo Id=”KI-C672A11E5F8017AFA114337688057903″>
<wsse:SecurityTokenReference wsu:Id=”STR-C672A11E5F8017AFA114337688058084″>
<wsse:Reference URI=”#X509-C672A11E5F8017AFA114337688056892″
ValueType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3″ />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp wsu:Id=”TS-C672A11E5F8017AFA114337688053671″>
<wsu:Created>2015-06-08T13:06:45Z</wsu:Created>
<wsu:Expires>2015-06-08T13:06:50Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soapenv:Header>
Appunti Crittografia
Problema: Bob e Alice si devono scambiare messaggio in modo che anche se viene intercettato nessuno lo possa decriptare ma lo possono leggere solo
i destinatari.
Possibile soluzione: Entrambi avranno una chiave Pubblica,che conoscono tutti, e una chiave privata, personale e segreta.
– Un messaggio cifrato con la chiave PUBBLICA di bob puo essere aperto solo dalla chiave PRIVATA di Bob. Quindi lo puo leggere solo lui. Il problema è che chiunque puo usare la chiave pubblica di Bob per cifrare quindi non sono sicuro che l abbia spedito Alice (Autenticita non rispettata)
– Un messaggio cifrato con la chiave PRIVATA di bob puo essere aperto solo dalla chiave PUBBLICA di Bob. Sono sicuro che il messaggio è stato mandato da Bob. Il problema è che chiunque abbia la chiave pubblica di Bob può leggere il messaggio(confidenzialità non rispettata)
– Un messaggio cifrato con la chiave privata si dice “FIRMATO“
–Firma digitale di un documento
tramite una funzione hash (pubblica) si ricava l’impronta digitale del documento, detta anche message digest, ossia un file di dimensioni relativamente piccole (160 bit) che contiene una sorta di codice di controllo relativo al documento stesso.
La funzione hash è fatta in modo da rendere minima la probabilità che da testi diversi si possa ottenere il medesimo valore dell’impronta, inoltre, è one-way, a senso unico, questo significa che dall’impronta è impossibile ottenere nuovamente il testo originario ovvero essa è non invertibile.
Dopodiché si utilizza la propria chiave privata per cifrare l’impronta digitale: il risultato di questa codifica è la firma. A questo punto la firma viene allegata al documento.Chiunque può verificare l’autenticità di un documento: per farlo, decifra la firma del documento con la chiave pubblica del mittente, ottenendo l’impronta digitale del documento, e quindi confronta quest’ultima con quella che si ottiene applicando la funzione hash al documento ricevuto; se le due impronte sono uguali, l’autenticità e l’integrità del documento sono garantite. Quindi quando qualcuno firma un documento garantisce che tutto quello scritto la dentro è vero. Il ricevente a modo di verificare che il contenuto non sia stato modificato durante il tragitto.
– Crittografia a chiave pubblica
Il mittente codifica due volte l’informazione:
• con la propria chiave privata
• con la chiave pubblica del destinatario
Il destinatario deve effettuare una doppia decodifica per leggere l’informazione:
• con la propria chiave privata
• con la chiave pubblica del mittente
In pratica, per motivi prestazionali, il client e il server usano questa tecnica per scambiarsi
una chiave simmetrica in modo sicuro e poi passano a un algoritmo di crittografia tradizionale
– Per evitare la necessità di scambiare in anticipo in modo sicuro le chiavi pubbliche, si usano certificati. Un certificato contiene una chiave pubblica autenticata mediante la firma digitale di una Certification Authority (CA). Chi riceve il certificato può verificare direttamente l’autenticità della chiave pubblica usando la chiave pubblica della CA (che deve essere nota).
-La maggior parte dei certificati comunemente utilizzati si basa sullo standard X.509 v3.
– il certificato quindi è la chiave pubblica di tizio, garantisce per questo chi ha emesso il certificato ossia la CA, firmandolo con la sua chiave privata
– In genere i certificati contengono le informazioni seguenti:
- il valore della chiave pubblica del soggetto
- informazioni di identificazione del soggetto, quali il nome e l’indirizzo di posta elettronica
- il periodo di validità (il periodo nel quale il certificato è considerato valido)
- informazioni di identificazione dell’autorità di certificazione
-I certificati (quindi le chiavi pubbliche)ritenuti “fidati” sono memorizzati in un truststore.
– Nel keystore sono memorizzate la nostra chiave pubblica e private
-il truststore ha lo stesso identico formato del keystore ma ha una funzione diversa. Nel keystore ci sono la chiave privata e un certificato. Nel truststore c è il certificato.
Funziona il tutto cosi:
il server preleva il suo certificato dal suo keystore e lo spedisce al client. Il client
verifica che il certificato deve appartenere al server. Ossia lo deve avere nel suo truststore.
Quindi nel truststore vengono memorizzati i certificati ritenuti affidabili.
In generale tutti i client SSL devono avere un truststore. Se il server SSL richiede anche
l’autenticazione del client allora deve avere anche lui un trustore.
Riassumento allora abbiamo che il keystore serve per fornire le credenziali (chiave privata e chiave pubblica) mentre il truststore per verificare la chiave pubblica (o certificato). Spesso il keystore e il keytrust sono nello stesso file
– Il keystore puo contenere coppie chiavi privata-certificato. Ogni coppia puo essere associata ad un alias.
– in java, in pratica, non si fa differenza tra trustore e keystore, si memorizza tutto nel keystore
-SSL supporta sia l’autenticazione lato server che quella lato client; nel primo caso, il più comune, il client controlla l’identità del server verificando che il certificato personale inviato dal server sia firmato da una CA che riconosce; per fare ciò deve disporre di un certificato emesso dalla CA che ha firmato la chiave pubblica del server.Nel caso di autenticazione lato client invece, è il server che controlla l’identità del client verificando che il certificato inviato da quest’ultimo sia firmato da una CA riconosciuta. Pertanto nell’autenticazione lato server, il client deve possedere solo il certificato della CA del server, mentre nell’autenticazione lato client deve possedere, oltre al certificato della CA del server, anche il suo certificato personale da inviare al server.
– Keystore e truststore sono gestiti tramite l’utility keytool del JDK.
–Comandi importare e visualizzare certificati
importa i certificati
keytool -import -alias <NOME ALIAS> -file <NOME FILE CERTIFICATO.CER> -keystore <NOME KEYSTORE> -storepass <PASSWORD KEYSTORE>
la password dei keystore in genere è changeit. Si puo anche creare un keystore personale e usare quello.
visualizza i certificati
keytool –list -v -keystore <NOME KEYSTORE>
– keystore di sistema:
$JAVA_HOME/lib/security/cacerts
Contiene i certificati delle CA riconosciute
-Keystore utente:
$HOME/.keystore
Contiene le chiavi dell’utente e quelle che l’utente riconosce
-mostra il contenuto di un certificato
openssl x509 -inform pem -in wild.ordenacionjuego.gob.es.cer -text
– file cer e file pem sono la stessa cosa
-Struttura di un certificato X.509 :
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING }
TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
— If present, version MUST be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
— If present, version MUST be v2 or v3
extensions [3] EXPLICIT Extensions OPTIONAL
— If present, version MUST be v3
}
-Un certificato PEM può essere letto con un semplice editor di testo e a al suo interno ha seguenti stringhe:
—–BEGIN CERTIFICATE—–
MIIB2zCCAUSgAwIBAwIBADANBgkqhkiG9w0BAQQFADAYMRYwFAYDVQQDEw1OZXRn
…
—–END CERTIFICATE—–
– si puo avere anche una private key in PEM format, in questo caso ci potrebbe essere la stringa:
-BEGIN RSA PRIVATE KEY—–