"File di firma non valido" quando si tenta di eseguire un file .jar


450

Il mio programma java è impacchettato in un file jar e fa uso di una libreria jar esterna, castello gonfiabile . Il mio codice viene compilato correttamente, ma l'esecuzione del jar porta al seguente errore:

Eccezione nel thread "main" java.lang.SecurityException: digest del file di firma non valido per gli attributi principali del manifest

Ho cercato su Google per più di un'ora alla ricerca di una spiegazione e ho trovato molto poco valore. Se qualcuno ha visto questo errore prima e potrebbe offrire un aiuto, sarei obbligato.


1
stai cercando di firmare il tuo barattolo? in tal caso, come stai tentando di firmarlo?
Cogsy,

No, almeno non penso di esserlo. Xcode potrebbe tentare di firmarlo da solo, ma non sembra esserci alcuna impostazione per disattivarlo.

non dimenticare di verificare se anche i barattoli contenenti interfacce implementate sono firmati!
gaurav

Risposte:


47

La soluzione elencata qui potrebbe fornire un puntatore.

Digest file di firma non valido per gli attributi principali Manifest

Linea di fondo :

Probabilmente è meglio mantenere il vaso ufficiale così com'è e aggiungerlo semplicemente come dipendenza nel file manifest per il file jar dell'applicazione.


3
Come rifletterò questo nel file manifest? Non ne ho mai modificato uno prima. Sto usando Xcode e la convenzione comune è quella di mettere le librerie jar esterne nella directory myproject / lib per l'inclusione, che è quello che sto facendo.

@ user123003 .. come nel caso di Intelli-J
MikeM,

13
Sfortunatamente alcuni di noi usano cose come "plug
Maven Shade

spina spudorata per rispondere su questo sito: stackoverflow.com/a/30922181/448779
foo

che dire di maven-assembly-plugin? Risolve questo problema nel mio caso
jhenya-d,

1083

Per coloro che hanno riscontrato questo errore durante il tentativo di creare un uber-jar con maven-shade-plugin, la soluzione è di escludere i file di firma manifest aggiungendo le seguenti righe alla configurazione del plug-in:

<configuration>
    <filters>
        <filter>
            <artifact>*:*</artifact>
            <excludes>
                <exclude>META-INF/*.SF</exclude>
                <exclude>META-INF/*.DSA</exclude>
                <exclude>META-INF/*.RSA</exclude>
            </excludes>
        </filter>
    </filters>
    <!-- Additional configuration. -->
</configuration>

9
Ho usato questo metodo per il mio Uber-Jar, e ha funzionato benissimo. C'è un esempio completo di POM su maven.apache.org/plugins/maven-shade-plugin/examples/… che mostra questo metodo per filtrare i file inclusi.
M. Dudley,

4
Sono stato tentato di iniziare un thread completamente nuovo - ma dato che questo è il numero 1 nei risultati di Google - mi è sembrato opportuno tenerlo qui. Le linee elencate qui si trovano nel file POM che sto usando - e sto ancora ottenendo l'errore di sicurezza durante l'esecuzione dell'applicazione. Si costruisce bene - e ovviamente funziona bene quando NON si fa un vaso Uber - come previsto. E mentre questa è sicuramente un'opzione - tienili separati - non risolve il problema se vuoi un Uber Jar.
Gavin Baumanis,

7
Questo funziona per me, ma ... perché abbiamo dovuto ignorare i file delle firme? Sono sicuro che il manifesto della firma ci sia per una ragione ...
Jeryl Cook,

4
Assicurati di fare "mvn clean" dopo aver fatto sopra!
codeinjuice,

4
@JerylCook I file delle firme sono lì per indicare che il contenuto di questo vaso ha questi file. Quando crei un barattolo superfluo, aggiungi un mucchio di file in più al barattolo, e quindi la firma non è corretta. Se lo volessi davvero, potresti ri-firmare il nuovo barattolo, ma ovviamente sarebbe con la tua firma, non quella vecchia. In alternativa, non è possibile distribuire il barattolo uber, ma includere invece il barattolo firmato come file separato, ma in primo luogo ciò vanifica lo scopo di un barattolo uber.
LadyCailin,

139

Per coloro che usano il gradle e cercano di creare e usare un vaso grasso, potrebbe essere utile la sintassi seguente.

jar {
    doFirst {
        from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' 
}

1
Questo praticamente esclude tutti i file con estensioni di .RSA, .SF o .DSA all'interno della directory META-INF.
Keith P,

9
La firma di un file jar aggiunge questi file in META-INF, ma quando sono inclusi, le firme non sono più in accordo con il contenuto del jar. Rimuovendoli si evita così la mancata corrispondenza della firma.
Peter N. Steinmetz,

1
V'è una domanda simile strettamente sull'utilizzo vaso grasso nel Gradle - stackoverflow.com/questions/4871656/...
Tomasz Sętkowski

3
Questo non ha funzionato per me. Ho dovuto mettere il excludemio fatJarcompito, che aveva quel configurations.compile.collectcomando. Vedi stackoverflow.com/a/31426413/103412
Torsten

1
Questo risolve anche l'erroreError: Could not find or load main class App Caused by: java.lang.ClassNotFoundException: App
vonox7,

57

Alcune delle tue dipendenze sono probabilmente file jar firmati. Quando li combini tutti in un unico file jar, i file delle firme corrispondenti sono ancora presenti e non corrispondono più al file jar "grande combinato", quindi il runtime si interrompe pensando che il file jar sia stato manomesso (che ... deve parlare).

È possibile risolvere il problema eliminando i file delle firme dalle dipendenze jarfile. Sfortunatamente, non è possibile farlo in un solo passaggio .

Tuttavia, sono stato in grado di farlo funzionare con Ant in due passaggi, senza nominare specificamente ogni dipendenza jarfile, usando:

<target name="jar" depends="compile" description="Create one big jarfile.">
    <jar jarfile="${output.dir}/deps.jar">
        <zipgroupfileset dir="jars">
            <include name="**/*.jar" />
        </zipgroupfileset>
    </jar>
    <sleep seconds="1" />
    <jar jarfile="${output.dir}/myjar.jar" basedir="${classes.dir}">
        <zipfileset src="${output.dir}/deps.jar" excludes="META-INF/*.SF" />
        <manifest>
            <attribute name="Main-Class" value="com.mycompany.MyMain" />
        </manifest>
    </jar>
</target>

Si suppone che l'elemento sleep prevenga errori sui file con date di modifica in futuro .

Altre varianti che ho trovato nei thread collegati non hanno funzionato per me.


È possibile farlo in un solo passaggio, utilizzando un modo diverso per specificare i vasi: <jar destfile = "build / myjar.jar"> <restrict> <not> <name name = "META-INF / *. SF" /> </not> <archives> <zips> <fileset dir = "jarfolder" include = " * / .jar" /> </zips> </archives> </restrict> </jar>
DieterDP

57

Si prega di utilizzare il seguente comando

zip -d yourjar.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'

4
Grazie, ho avuto questo problema con intellij 14 e la tua soluzione funziona per me!
Mohamad Kouhi Moghadam,

5
Grazie, ha lavorato per me in Windows. Ho appena aperto il vaso con 7zip, cancellato i file .SF. Non avevo file .RSA da eliminare
candino

3
Wow, posso solo dire che questa soluzione è stata incredibile (e ho imparato qualcosa di molto potente lungo la strada!) Questo ha bisogno di più voti.
Dylan_Larkin,

Sono d'accordo con il commento di @Dylan_Larkin, questo è ciò che ha risolto per me.
Felipe Valdes,

26

Ho avuto questo problema durante l'utilizzo di IntelliJ IDEA 14.01.

Sono stato in grado di risolverlo:

File-> Struttura del progetto-> Aggiungi nuovo (artefatti) -> vaso-> Da moduli con dipendenze nella finestra Crea vaso da modulo:

Seleziona la tua classe principale

File JAR dalle librerie Selezionare copia nella directory di output e collegamento tramite manifest


2
È possibile mettere i barattoli dipendenti nel barattolo bersaglio?
coder.chenzhi,

le tue soluzioni funzionano bene !! grazie molto!
hzitoun

19

La sicurezza è già un argomento difficile, ma sono deluso nel vedere che la soluzione più popolare è eliminare le firme di sicurezza. JCE richiede queste firme . La tonalità Maven esplode il file jar di BouncyCastle che inserisce le firme in META-INF, ma le firme BouncyCastle non sono valide per un nuovo, uber-jar (solo per il vaso BC), ed è ciò che causa l'errore di firma non valido in questo thread .

Sì, l'esclusione o l'eliminazione delle firme come suggerito da @ruhsuzbaykus fa sì che l'errore originale scompaia, ma può anche portare a nuovi errori criptici:

java.security.NoSuchAlgorithmException: PBEWithSHA256And256BitAES-CBC-BC SecretKeyFactory not available

Specificando esplicitamente dove trovare l'algoritmo in questo modo:

SecretKeyFactory.getInstance("PBEWithSHA256And256BitAES-CBC-BC","BC");

Sono stato in grado di ottenere un errore diverso:

java.security.NoSuchProviderException: JCE cannot authenticate the provider BC

JCE non può autenticare il provider perché abbiamo eliminato le firme crittografiche seguendo il suggerimento altrove in questo stesso thread .

La soluzione che ho trovato era il plug-in eseguibile packer che utilizza un approccio jar-in-jar per preservare la firma BouncyCastle in un singolo jar eseguibile.

AGGIORNAMENTO :

Un altro modo per farlo (il modo corretto?) È usare il firmatario Maven Jar . Ciò ti consente di continuare a utilizzare Maven shade senza ottenere errori di sicurezza. TUTTAVIA, è necessario disporre di un certificato di firma del codice (Oracle suggerisce di cercare "Certificato di firma del codice Java"). La configurazione POM è simile alla seguente:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <filters>
                    <filter>
                        <artifact>org.bouncycastle:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>your.class.here</mainClass>
                    </transformer>
                </transformers>
                <shadedArtifactAttached>true</shadedArtifactAttached>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jarsigner-plugin</artifactId>
    <version>1.4</version>
    <executions>
        <execution>
            <id>sign</id>
            <goals>
                <goal>sign</goal>
            </goals>
        </execution>
        <execution>
            <id>verify</id>
            <goals>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <keystore>/path/to/myKeystore</keystore>
        <alias>myfirstkey</alias>
        <storepass>111111</storepass>
        <keypass>111111</keypass>
    </configuration>
</plugin>

No, non c'è modo di far riconoscere a JCE un certificato autofirmato, quindi se è necessario conservare i certificati BouncyCastle, è necessario utilizzare il plug-in jar-in-jar o ottenere un certificato JCE.


Questo è sicuramente il modo giusto per farlo, anche se richiede molto lavoro. Grazie per aver sottolineato, in dettaglio, le avvertenze con l'utilizzo della risposta approvata. Sai se il certificato JCE deve essere firmato da Sun? O può
WiteCastle il

1
Esistono terze parti che possono emettere certificati di firma codice. Cerca "Certificato di firma codice Java" per visualizzare le opzioni.
Matt

Lei, signore, ha reso la mia giornata!
socona,

Aiutato per me Ci sono alcuni file in questa libreria che non uso, quindi tranne loro mi aiutano con il file fat-jar
Saidolim,

14

Ho affrontato lo stesso problema, dopo riferimento da qualche parte, ha funzionato come di seguito cambiando:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.1</version>
    <configuration>
        <createDependencyReducedPom>false</createDependencyReducedPom>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <filters>
                    <filter>
                        <artifact>*:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
            </configuration>
        </execution>
    </executions>
</plugin>

1
Questo ha risolto rapidamente il mio problema! Per completezza, questo dovrebbe andare nel maven-shade-plugintag.
Kuzeko,

1
@Kuzeko Hai aggiornato la risposta con il tuo suggerimento. Grazie
m.nguyencntt il

8

Supponendo che tu costruisca il tuo file jar con ant, puoi semplicemente indicare a form di lasciare la directory META-INF. Questa è una versione semplificata del mio bersaglio formica:

<jar destfile="app.jar" basedir="${classes.dir}">
    <zipfileset excludes="META-INF/**/*" src="${lib.dir}/bcprov-jdk16-145.jar"></zipfileset>
    <manifest>
        <attribute name="Main-Class" value="app.Main"/>
    </manifest>
</jar>

dove dovrei aggiungere queste righe?
Addi.Star

4

Di recente ho iniziato a utilizzare IntelliJ nei miei progetti. Tuttavia, alcuni dei miei colleghi usano ancora Eclipse per gli stessi progetti. Oggi ho lo stesso errore dopo aver eseguito il file jar creato dal mio IntelliJ. Mentre tutte le soluzioni qui parlano quasi della stessa cosa, nessuna di queste ha funzionato facilmente per me (probabilmente perché non uso ANT, maven build mi ha dato altri errori che mi hanno fatto riferimento a http://cwiki.apache.org/ confluenza / display / MAVEN / MojoExecutionException , e inoltre non sono riuscito a capire quali sono i barattoli firmati da solo!)

Alla fine, questo mi ha aiutato

zip -d demoSampler.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'

Indovina cosa è stato rimosso dal mio file jar ?!

deleting: META-INF/ECLIPSE_.SF 
deleting: META-INF/ECLIPSE_.RSA

Sembra che il problema fosse rilevante per alcuni file rilevanti per l'eclissi.


4

Ho avuto lo stesso problema gradledurante la creazione di un grosso Jar, l'aggiornamento del build.gradlefile con una riga di esclusione ha corretto il problema.

jar {
    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
    manifest {
        attributes 'Main-Class': 'com.test.Main'
    }
}

1
Sono stato il debug per giorni, questo ha risolto il mio problema con il vasetto di grasso.
sysuser

Il modo in cui ho eseguito il debug è di mettere il fat jar nella directory lib di jmeter. Se avete il vaso problematico in lib / ext, questo problema non sarà evidente, piuttosto si otterrà un errore come quello in stackoverflow.com/questions/37624187/...
SYSUSER

1
escludi "META-INF / *. RSA", "META-INF / *. SF", "META-INF / *. DSA" Questo mancava, alcuni
vasi

3

Nel caso in cui utilizzi il gradle, ecco un'attività farJar completa:

version = '1.0'
//create a single Jar with all dependencies
task fatJar(type: Jar) {
    manifest {
        attributes 'Implementation-Title': 'Gradle Jar File Example',  
            'Implementation-Version': version,
            'Main-Class': 'com.example.main'
    }
    baseName = project.name + '-all'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' 
    with jar
}

2

Confronta la cartella META-INF nel nuovo vaso con il vecchio vaso (prima di aggiungere nuove librerie). È possibile che ci siano nuovi file. Se sì, puoi rimuoverli. Dovrebbe aiutare. Saluti, 999michal


2

Una strategia consisterebbe nell'usare ANT per semplificare la rimozione della firma da ciascun file Jar. Procederebbe con i seguenti passaggi:

  1. Copia di MANIFEST.MF in un file temporaneo
  2. Rimozione delle voci Nome e SHA dal file temporaneo
  3. Creazione di un file Jar temporaneo con manifest temporaneo
  4. Rimozione del manifest temporaneo
  5. Scambiare il file Jar originale con quello temporaneo

Ecco un macrodef ANT che fa il lavoro:

<macrodef name="unsignjar" description="To unsign a specific Jar file">
    <attribute name="jarfile" 
        description="The jar file to unsign" />
    <sequential>
<!-- Copying to the temporary manifest file -->
        <copy toFile="@{jarFile}_MANIFEST.tmp">
            <resources>
                <zipentry zipfile="@{jarFile}" name="META-INF/MANIFEST.MF"/>
            </resources>
        </copy>
<!-- Removing the Name and SHA entries from the temporary file -->
        <replaceregexp file="@{jarFile}_MANIFEST.tmp" match="\nName:(.+?)\nSH" replace="SH" flags="gis" byline="false"/>
        <replaceregexp file="@{jarFile}_MANIFEST.tmp" match="SHA(.*)" replace="" flags="gis" byline="false"/>
<!-- Creating a temporary Jar file with the temporary manifest -->
        <jar jarfile="@{jarFile}.tmp"
            manifest="@{jarFile}_MANIFEST.tmp">
            <zipfileset src="@{jarFile}">
                <include name="**"/>
                <exclude name="META-INF/*.SF"/>
                <exclude name="META-INF/*.DSA"/>
                <exclude name="META-INF/*.RSA"/>
            </zipfileset>
        </jar>
<!-- Removing the temporary manifest -->
        <delete file="@{jarFile}_MANIFEST.tmp" />
<!-- Swapping the original Jar file with the temporary one -->
        <move file="@{jarFile}.tmp"
              tofile="@{jarFile}"
              overwrite="true" />
</sequential>

`

La definizione può quindi essere chiamata in questo modo in un'attività ANT:

<target name="unsignJar">
    <unsignjar jarFile="org.test.myjartounsign.jar" />
</target>

2

Errore: si è verificato un errore JNI, controllare l'installazione e riprovare Eccezione nel thread "main" java.lang.SecurityException: digest del file della firma non valido per gli attributi principali del manifest su sun.security.util.SignatureFileVerifier.processImpl (SignatureFileVerifier.java: 314) at sun.security.util.SignatureFileVerifier.process (SignatureFileVerifier.java:268) at java.util.jar.JarVerifier.processEntry (JarVerifier.java:316) at java.util.jar.JarVerifier.update (JarVerifier.update : 228) at java.util.jar.JarFile.initializeVerifier (JarFile.java:383) at java.util.jar.JarFile.getInputStream (JarFile.java:450) at sun.misc.URLClassPath $ JarLoader $ 2.getInputStream (URLClassPath .java: 977) a sun.misc.Resource.cachedInputStream (Resource.java:77) a sun.misc.Resource.getByteBuffer (Resource.java:160) at java.net.URLClassLoader.defineClass (URLClassLoader.java:454) at java.net.URLClassLoader.access $ 100 (URLClassLoader.java:73) at java.net.URLClassLoader $ 1.run (URLClassLoader.java:368) at java.net.URLClassLoader $ 1.run (URLClassLoader.java:362) su java.security.AccessController.doPrivileged (metodo nativo) su java.net.URLClassLoader.findClass (URLClassLoader.java:361) su java.lang.ClassLoader.loadClass (ClassLoader.java:424) at sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.java:331) at java.lang.ClassLoader.loadClass (ClassLoader.java:357) at sun.launcher.LauncherHelper.checkAndLoadMain (LauncherHelper.checkAndLoadMain (LauncherHelper.checkAndLoadMain). java: 495)eseguire (URLClassLoader.java:368) su java.net.URLClassLoader $ 1.run (URLClassLoader.java:362) su java.security.AccessController.doPrivileged (metodo nativo) su java.net.URLClassLoader.findClass (URLClassLoader.java:361 ) at java.lang.ClassLoader.loadClass (ClassLoader.java:424) at sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.java:331) at java.lang.ClassLoader.loadClass (ClassLoader.java:357) at sun .launcher.LauncherHelper.checkAndLoadMain (LauncherHelper.java:495)eseguire (URLClassLoader.java:368) su java.net.URLClassLoader $ 1.run (URLClassLoader.java:362) su java.security.AccessController.doPrivileged (metodo nativo) su java.net.URLClassLoader.findClass (URLClassLoader.java:361 ) at java.lang.ClassLoader.loadClass (ClassLoader.java:424) at sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.java:331) at java.lang.ClassLoader.loadClass (ClassLoader.java:357) at sun .launcher.LauncherHelper.checkAndLoadMain (LauncherHelper.java:495)331) at java.lang.ClassLoader.loadClass (ClassLoader.java:357) at sun.launcher.LauncherHelper.checkAndLoadMain (LauncherHelper.java:495)331) at java.lang.ClassLoader.loadClass (ClassLoader.java:357) at sun.launcher.LauncherHelper.checkAndLoadMain (LauncherHelper.java:495)

Cosa mi ha aiutato (IntelliJ IDEA 2016.3): File -> Struttura del progetto -> Manufatti -> Aggiungi JAR -> Seleziona classe principale -> Scegli "copia nella directory di output e collega tramite manifest" -> OK -> Applica -> Crea - > Costruisci artefatti ... -> Costruisci



1

Se stai cercando una soluzione Fat JAR senza disimballare o manomettere le librerie originali ma con uno speciale caricatore di classi JAR, dai un'occhiata al mio progetto qui .

Dichiarazione di non responsabilità: non ho scritto il codice, ma solo impacchettato e pubblicato su Maven Central e descrivo nel mio read-me come usarlo.

Lo uso personalmente per creare JAR eseguibili contenenti dipendenze BouncyCastle. Forse è utile anche per te.


0

Per coloro che hanno problemi con la soluzione accettata, c'è un altro modo per escludere risorse dal vaso ombreggiato con DontIncludeResourceTransformer:

https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html#DontIncludeResourceTransformer

          <transformers>
            <transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
                <resource>BC1024KE.DSA</resource>
            </transformer>
          </transformers>

Da Shade 3.0, questo trasformatore accetta un elenco di risorse. Prima di allora devi solo usare più trasformatori ciascuno con una risorsa.


0

Questo mi è successo in Intellij quando ho fatto clic su "Aggiungi come progetto Maven" nella linea di fondo quando Intellij ha detto "trovati file pom non gestiti". Nel frattempo la cartella out era già stata generata. Quindi non ha ricevuto modifiche recenti.

L'eliminazione della cartella e l'esecuzione del programma hanno risolto il problema per me. la cartella out è stata quindi ricreata.

Vedi anche la risposta di Little Fox. L'errore che ho ricevuto era molto simile al suo.


-1

Ho avuto un problema simile. Il motivo era che stavo compilando usando un JDK con un JRE diverso da quello predefinito nella mia finestra di Windows.

Utilizzando il java.exe corretto ho risolto il mio problema.


-2

Se stai ottenendo questo quando provi a associare i file JAR per un progetto Xamarin.Android in questo modo:

JARTOXML: avviso J2XA006: errore di classe mancante generato durante la riflessione di com.your.class: digest del file di firma non valido per gli attributi principali del manifest

Basta aprire i file JAR usando Winzip ed eliminare le directory meta-inf. Ricostruisci - lavoro fatto


1
Questa è una tecnica orribile. Assolutamente orribile. Apporta le correzioni localmente non apportare modifiche ai barattoli in arrivo
sinisterrook,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.