Comment crypter une chaîne en Java


Ce dont j'ai besoin, c'est de chiffrer la chaîne qui apparaîtra dans le code à barres 2D(PDF-417), donc quand quelqu'un aura une idée de scanner, il n'aura rien de lisible.

Autres exigences:

  • ne devrait pas être compliqué
  • il ne doit pas être composé de RSA, d'infrastructure PKI, de paires de clés, etc.

Il doit être assez simple pour se débarrasser des gens qui fouinent autour, et facile à décrypter pour les autres entreprises intéressées à obtenir ces données. Ils nous appellent, nous leur disons la norme ou donnez-leur une clé simple qui peut ensuite être utilisée pour le décryptage.

Probablement ces entreprises pourraient utiliser différentes technologies, il serait donc bon de s'en tenir à une norme qui n'est pas liée à une plate-forme ou à une technologie spéciale.

Que suggérez-vous? Existe-t-il une classe Java qui fait encrypt() decrypt() sans trop de complication pour atteindre des normes de sécurité élevées?

Author: Glenn, 2009-07-30

15 answers

Je vous recommande d'utiliser un standard symétrique monogramme qui est largement disponible comme DES, 3DES ou AES. Bien que ce ne soit pas l'algorithme le plus sécurisé, il existe de nombreuses implémentations et il vous suffit de donner la clé à quiconque est censé déchiffrer les informations contenues dans le code à barres. javax.cryptographique.Cipher est ce avec quoi vous voulez travailler ici.

Supposons que les octets à chiffrer sont dans

byte[] input;

Ensuite, vous aurez besoin de la clé et vecteur d'initialisation octets

byte[] keyBytes;
byte[] ivBytes;

Vous pouvez maintenant initialiser le chiffrement de l'algorithme que vous sélectionnez:

// wrap key data in Key/IV specs to pass to cipher
SecretKeySpec key = new SecretKeySpec(keyBytes, "DES");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
// create the cipher with the algorithm you choose
// see javadoc for Cipher class for more info, e.g.
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

Cryptage irait comme ceci:

cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
byte[] encrypted= new byte[cipher.getOutputSize(input.length)];
int enc_len = cipher.update(input, 0, input.length, encrypted, 0);
enc_len += cipher.doFinal(encrypted, enc_len);

Et le déchiffrement comme ceci:

cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
byte[] decrypted = new byte[cipher.getOutputSize(enc_len)];
int dec_len = cipher.update(encrypted, 0, enc_len, decrypted, 0);
dec_len += cipher.doFinal(decrypted, dec_len);
 110
Author: VoidPointer, 2013-11-05 16:34:11

C'est la première page qui apparaît via Google et la sécurité les vulnérabilités dans toutes les implémentations me font grincer des dents donc je suis poster ceci pour ajouter des informations concernant le cryptage pour les autres comme il a été 7 ans du poste original. Je suis titulaire d'un Master en Génie informatique et a passé beaucoup de temps à étudier et à apprendre Cryptographie donc je jette mes deux cents pour faire d'Internet un endroit plus sûr.

Aussi, notez que a beaucoup d'implémentation peut être sécurisée pour une donnée situation, mais pourquoi les utiliser et potentiellement accidentellement faire un erreur? Utilisez les outils les plus puissants dont vous disposez, sauf si vous avez un raison spécifique de ne pas le faire. Dans l'ensemble je conseille fortement d'utiliser une bibliothèque et rester loin des détails nitty gritty si vous le pouvez.

MISE À JOUR 4/5/18: J'ai réécrit certaines parties pour les rendre plus simples à comprendre et changé la bibliothèque recommandée de Jasypt à nouveau Google bibliothèque Tink , je recommanderais de supprimer complètement Jasypt d'une configuration existante.

Avant-propos

Je vais décrire les bases de la cryptographie symétrique sécurisée ci-dessous et souligner les erreurs courantes que je vois en ligne lorsque les gens implémentent eux-mêmes la cryptographie avec la bibliothèque Java standard. Si vous voulez simplement ignorer tous les détails, passez à La nouvelle bibliothèque de Google Tink importez-la dans votre projet et utilisez le mode AES-GCM pour tous vos chiffrement et vous serez en sécurité.

Maintenant, si vous voulez apprendre les détails concrets sur la façon de chiffrer en java lire sur :)

Chiffrements de bloc

Première chose vous devez d'abord choisir un chiffrement par bloc de clé symétrique. Un chiffrement par bloc est une fonction/programme informatique utilisé pour créer un pseudo-aléatoire. Le pseudo-hasard est un faux hasard qu'aucun ordinateur autre qu'un ordinateur quantique ne serait capable de faire la différence entre celui-ci et le hasard réel. bloc Le chiffrement est comme le bloc de construction de la cryptographie, et lorsqu'il est utilisé avec différents modes ou schémas, nous pouvons créer des chiffrements.

Maintenant, en ce qui concerne les algorithmes de Chiffrement par bloc disponibles aujourd'hui, Assurez-vous de NE JAMAIS , je répète NE JAMAIS utiliser DES , je dirais même NE JAMAIS utiliser 3DES . Le seul Chiffrement par bloc que même la version de la NSA de Snowden a pu vérifier étant vraiment aussi proche que possible du Pseudo-aléatoire estAES 256 . Il existe également AES 128, le la différence est que AES 256 fonctionne dans des blocs de 256 bits, tandis que AES 128 fonctionne dans des blocs de 128. Dans l'ensemble, AES 128 est considéré comme sécurisé bien que certaines faiblesses aient été découvertes, mais 256 est aussi solide que possible.

Fun fact DES a été brisé par la NSA lors de sa création initiale et a en fait gardé un secret pendant quelques années et bien que certaines personnes prétendent toujours que 3DES est sécurisé, il y a pas mal d'articles de recherche qui ont trouvé et analysé des faiblesses dans 3DES.

Les Modes De Chiffrement

Le chiffrement est créé lorsque vous prenez un chiffrement par bloc et utilisez un schéma spécifique afin que le caractère aléatoire soit combiné avec une clé pour créer quelque chose qui est réversible tant que vous connaissez la clé. C'est ce qu'on appelle un mode de cryptage.

Voici un exemple d'un mode de cryptage et le mode le plus simple connu sous le nom ECB juste pour que vous puissiez comprendre visuellement ce qui se passe:

Mode BCE

Le les modes de cryptage que vous verrez le plus souvent en ligne sont les suivants:

BCE CTR, CBC, CMG

Il existe d'autres modes en dehors de ceux énumérés et les chercheurs travaillent toujours vers de nouveaux modes pour améliorer les problèmes existants.

Passons maintenant aux implémentations et à ce qui est sécurisé. NE JAMAIS utiliser ECB c'est mauvais pour cacher des données répétitives comme le montre le célèbreLinux penguin .Exemple Linux Penguin

Lors de l'implémentation en Java, notez que si vous utilisez le code suivant, le mode ECB est défini par défaut:

Cipher cipher = Cipher.getInstance("AES");

... DANGER C'EST UNE VULNÉRABILITÉ! et malheureusement, cela se voit partout dans StackOverflow et en ligne dans les tutoriels et les exemples.

Nonces et IVs

En réponse à la question trouvée avec le mode BCE, des noms également connus sous le nom de IV ont été créés. L'idée est que nous générons une nouvelle variable aléatoire et l'attachons à chaque cryptage de sorte que lorsque vous chiffrez deux messages qui sont les mêmes ils sortent différents. La beauté derrière cela est qu'un IV ou nonce est de notoriété publique. Cela signifie qu'un attaquant peut y avoir accès, mais tant qu'il n'a pas votre clé, il ne peut rien faire avec cette connaissance.

Les problèmes courants que je verrai sont que les gens définiront le IV comme une valeur statique comme dans la même valeur fixe dans leur code. et voici l'écueil à IVs au moment où vous répétez un vous compromettez réellement toute la sécurité de votre cryptage.

Générer Un IV Aléatoire

SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG");
byte[] iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);

Remarque: SHA1 est cassé mais je n'ai pas trouvé comment implémenter correctement SHA256 dans ce cas d'utilisation, donc si quelqu'un veut prendre une fissure à cela et mettre à jour ce serait génial! Aussi les attaques SHA1 sont toujours non conventionnelles car il peut prendre quelques années sur un énorme cluster pour se fissurer. découvrez les détails ici.

Mise en œuvre du CTR

Aucun remplissage n'est requis pour CTR mode.

 Cipher cipher = Cipher.getInstance("AES/NoPadding");

Mise en œuvre de CBC

Si vous choisissez d'implémenter le mode CBC, faites-le avec PKCS7Padding comme suit:

 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");

Vulnérabilité CBC et CTR et Pourquoi Vous devriez utiliser GCM

Bien que certains autres modes tels que CBC et CTR soient sécurisés, ils rencontrent le problème où un attaquant peut retourner les données cryptées, en modifiant leur valeur lorsqu'elles sont déchiffrées. Disons donc que vous chiffrez un message bancaire imaginaire "Vendre 100", votre message crypté ressemble à ceci "eu23ng" l'attaquant change un peu à " eu53ng "et tout d'un coup quand déchiffré votre message, il se lit comme"Vendre 900".

Pour éviter cela, la majorité d'Internet utilise GCM, et chaque fois que vous voyez HTTPS, ils utilisent probablement GCM. GCM signe le message chiffré avec un hachage et vérifie que le message n'a pas été modifié à l'aide de cette signature.

J'éviterais d'implémenter GCM en raison de sa complexité. Il vaut mieux utiliser Googles new library Tink parce que là encore, si vous répétez accidentellement une IV, vous compromettez la clé dans le cas de GCM, ce qui est la faille de sécurité ultime. De nouveaux chercheurs travaillent vers des modes de cryptage résistants à la répétition IV où même si vous répétez l'IV, la clé n'est pas en danger, mais cela n'a pas encore été généralisé.

Maintenant, si vous voulez implémenter GCM, voici un lien vers une belle implémentation GCM . Cependant, je ne peux pas assurer la sécurité ou si c'est correctement mis en œuvre mais il obtient la base vers le bas. Notez également qu'avec GCM, il n'y a pas de rembourrage.

Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

Clés vs mots de passe

Une autre note très importante, c'est que lorsqu'il s'agit de cryptographie, une Clé et un Mot de passe ne sont pas les mêmes choses. Une clé en cryptographie doit avoir une certaine entropie et un caractère aléatoire pour être considérée comme sécurisée. C'est pourquoi vous devez vous assurer d'utiliser le bon bibliothèques cryptographiques pour générer la clé pour vous.

Donc vous avez vraiment deux implémentations que vous pouvez faire ici, la première est d'utiliser le code trouvé sur ce thread StackOverflow pour la génération aléatoire de clés. Cette solution utilise un générateur de nombres aléatoires sécurisé pour créer une clé à partir de zéro que vous pouvez utiliser.

L'autre option moins sécurisée consiste à utiliser une entrée utilisateur telle qu'un mot de passe. Le problème que nous avons discuté est que le mot de passe n'a pas assez d'entropie, nous devrions donc utiliser PBKDF2, un algorithme qui prend le mot de passe et renforce il. Voici une implémentation de StackOverflow que j'ai aimé . Cependant, Google Tink Library a tout cela intégré et vous devriez en profiter.

Les Développeurs Android

Un point important à souligner ici est de savoir que votre code Android est inverse enginerable et la plupart des cas, la plupart du code java l'est aussi. Cela signifie que si vous stockez le mot de passe en texte brut dans votre code. Un pirate peut facilement le récupérer. Habituellement, pour ce type de cryptage, vous souhaitez utiliser Cryptographie asymétrique et ainsi de suite. Ceci est en dehors de la portée de ce post, donc je vais éviter de plonger dedans.

Une lecture intéressante de 2013: Souligne que 88% des implémentations cryptographiques dans Android ont été effectuées de manière incorrecte.

Réflexions Finales

Encore une fois, je suggère d'éviter d'implémenter la bibliothèque java pour crypto directement et d'utiliser Google Tink , cela vous évitera le mal de tête car ils ont vraiment fait un bon travail d'implémentation de tous les algorithmes correctement. Et même alors, assurez-vous de vérifier les problèmes soulevés sur le Tink github, vulnérabilités popup ici et là.

Si vous avez des questions ou des commentaires n'hésitez pas à commenter! La sécurité est en constante évolution et vous devez faire de votre mieux pour la suivre:)

 65
Author: Konstantino Sparakis, 2018-04-06 12:32:39

Avertissement

Ne l'utilisez pas comme une sorte de mesure de sécurité.

Le mécanisme de cryptage dans ce post est un pad unique, ce qui signifie que la clé secrète peut être facilement récupérée par un attaquant en utilisant 2 messages cryptés. XOR 2 messages cryptés et vous obtenez la clé. Aussi simple que cela!

Souligné par Moussa


J'utilise le Base64Encoder/Decoder de Sun qui se trouve dans le JRE de Sun, pour éviter encore un autre POT en lib. C'est dangereux du point de vue de l'utilisation d'OpenJDK ou de JRE d'un autre. En plus de cela, y a-t-il une autre raison pour laquelle je devrais envisager d'utiliser Apache commons lib avec Encoder/Decoder?

public class EncryptUtils {
    public static final String DEFAULT_ENCODING = "UTF-8"; 
    static BASE64Encoder enc = new BASE64Encoder();
    static BASE64Decoder dec = new BASE64Decoder();

    public static String base64encode(String text) {
        try {
            return enc.encode(text.getBytes(DEFAULT_ENCODING));
        } catch (UnsupportedEncodingException e) {
            return null;
        }
    }//base64encode

    public static String base64decode(String text) {
        try {
            return new String(dec.decodeBuffer(text), DEFAULT_ENCODING);
        } catch (IOException e) {
            return null;
        }
    }//base64decode

    public static void main(String[] args) {
        String txt = "some text to be encrypted";
        String key = "key phrase used for XOR-ing";
        System.out.println(txt + " XOR-ed to: " + (txt = xorMessage(txt, key)));

        String encoded = base64encode(txt);       
        System.out.println(" is encoded to: " + encoded + " and that is decoding to: " + (txt = base64decode(encoded)));
        System.out.print("XOR-ing back to original: " + xorMessage(txt, key));
    }

    public static String xorMessage(String message, String key) {
        try {
            if (message == null || key == null) return null;

            char[] keys = key.toCharArray();
            char[] mesg = message.toCharArray();

            int ml = mesg.length;
            int kl = keys.length;
            char[] newmsg = new char[ml];

            for (int i = 0; i < ml; i++) {
                newmsg[i] = (char)(mesg[i] ^ keys[i % kl]);
            }//for i

            return new String(newmsg);
        } catch (Exception e) {
            return null;
        }
    }//xorMessage
}//class
 22
Author: ante.sabo, 2016-05-31 11:46:42

Merci d'avoir fait cette classe en utilisant votre code peut-être que quelqu'un le trouve userfull

Crypter d'objet

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


public class ObjectCrypter {

private Cipher deCipher;
private Cipher enCipher;
private SecretKeySpec key;
private IvParameterSpec ivSpec;


public ObjectCrypter(byte[] keyBytes,   byte[] ivBytes) {
    // wrap key data in Key/IV specs to pass to cipher


     ivSpec = new IvParameterSpec(ivBytes);
    // create the cipher with the algorithm you choose
    // see javadoc for Cipher class for more info, e.g.
    try {
         DESKeySpec dkey = new  DESKeySpec(keyBytes);
          key = new SecretKeySpec(dkey.getKey(), "DES");
         deCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
         enCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
public byte[] encrypt(Object obj) throws InvalidKeyException, InvalidAlgorithmParameterException, IOException, IllegalBlockSizeException, ShortBufferException, BadPaddingException {
    byte[] input = convertToByteArray(obj);
    enCipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);

    return enCipher.doFinal(input);




//  cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
//  byte[] encypted = new byte[cipher.getOutputSize(input.length)];
//  int enc_len = cipher.update(input, 0, input.length, encypted, 0);
//  enc_len += cipher.doFinal(encypted, enc_len);
//  return encypted;


}
public Object decrypt( byte[]  encrypted) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException, ClassNotFoundException {
    deCipher.init(Cipher.DECRYPT_MODE, key, ivSpec);

    return convertFromByteArray(deCipher.doFinal(encrypted));

}



private Object convertFromByteArray(byte[] byteObject) throws IOException,
        ClassNotFoundException {
    ByteArrayInputStream bais;

    ObjectInputStream in;
    bais = new ByteArrayInputStream(byteObject);
    in = new ObjectInputStream(bais);
    Object o = in.readObject();
    in.close();
    return o;

}



private byte[] convertToByteArray(Object complexObject) throws IOException {
    ByteArrayOutputStream baos;

    ObjectOutputStream out;

    baos = new ByteArrayOutputStream();

    out = new ObjectOutputStream(baos);

    out.writeObject(complexObject);

    out.close();

    return baos.toByteArray();

}


}
 12
Author: sherif, 2010-09-18 18:59:19

Que diriez-vous de ceci:

private static byte[] xor(final byte[] input, final byte[] secret) {
    final byte[] output = new byte[input.length];
    if (secret.length == 0) {
        throw new IllegalArgumentException("empty security key");
    }
    int spos = 0;
    for (int pos = 0; pos < input.length; ++pos) {
        output[pos] = (byte) (input[pos] ^ secret[spos]);
        ++spos;
        if (spos >= secret.length) {
            spos = 0;
        }
    }
    return output;
}

Fonctionne bien pour moi et est plutôt compact.

 7
Author: yegor256, 2012-12-26 15:59:34

Voici mon implémentation de meta64.com comme un Singleton de printemps. Si vous souhaitez créer une instance ciper pour chaque appel qui fonctionnerait également, vous pouvez supprimer les appels "synchronisés", mais attention, "cipher" n'est pas thread-safe.

import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("singleton")
public class Encryptor {

    @Value("${aeskey}")
    private String keyStr;

    private Key aesKey = null;
    private Cipher cipher = null;

    synchronized private void init() throws Exception {
        if (keyStr == null || keyStr.length() != 16) {
            throw new Exception("bad aes key configured");
        }
        if (aesKey == null) {
            aesKey = new SecretKeySpec(keyStr.getBytes(), "AES");
            cipher = Cipher.getInstance("AES");
        }
    }

    synchronized public String encrypt(String text) throws Exception {
        init();
        cipher.init(Cipher.ENCRYPT_MODE, aesKey);
        return toHexString(cipher.doFinal(text.getBytes()));
    }

    synchronized public String decrypt(String text) throws Exception {
        init();
        cipher.init(Cipher.DECRYPT_MODE, aesKey);
        return new String(cipher.doFinal(toByteArray(text)));
    }

    public static String toHexString(byte[] array) {
        return DatatypeConverter.printHexBinary(array);
    }

    public static byte[] toByteArray(String s) {
        return DatatypeConverter.parseHexBinary(s);
    }

    /*
     * DO NOT DELETE
     * 
     * Use this commented code if you don't like using DatatypeConverter dependency
     */
    // public static String toHexStringOld(byte[] bytes) {
    // StringBuilder sb = new StringBuilder();
    // for (byte b : bytes) {
    // sb.append(String.format("%02X", b));
    // }
    // return sb.toString();
    // }
    //
    // public static byte[] toByteArrayOld(String s) {
    // int len = s.length();
    // byte[] data = new byte[len / 2];
    // for (int i = 0; i < len; i += 2) {
    // data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i +
    // 1), 16));
    // }
    // return data;
    // }
}
 5
Author: mkobit, 2015-08-03 18:17:37

J'envisagerais d'utiliser quelque chose comme https://www.bouncycastle.org / C'est une bibliothèque prédéfinie qui vous permet de chiffrer ce que vous voulez avec un certain nombre de chiffrements différents Je comprends que vous voulez seulement vous protéger contre l'espionnage, mais si vous voulez vraiment protéger les informations, l'utilisation de Base64 ne vous protégera pas réellement.

 4
Author: hdost, 2015-01-06 21:26:08

Voici quelques liens que vous pouvez lire ce que Java prend en charge

Chiffrer / déchiffrer un flux de données.

Cet exemple montre comment chiffrer (en utilisant un chiffrement symétrique algorithme tel que AES, Blowfish, RC2, 3DES, etc) une grande quantité de données. Le les données sont transmises en morceaux à l'un des méthodes de chiffrement: EncryptBytes, EncryptString, EncryptBytesENC, ou EncryptStringENC. (Le nom de la méthode indique le type d'entrée (ou chaîne tableau d'octets) et le type de retour (chaîne codée ou le tableau d'octets). Le Propriétés FirstChunk et LastChunk sont utilisés pour indiquer si un morceau est le premier, le milieu ou le dernier dans un flux chiffrés. Par défaut, FirstChunk et LastChunk sont égaux vrai meaning ce qui signifie que les données sont passées est la totalité de la somme.

JCERefGuide

Exemples de chiffrement Java

 3
Author: Markus Lausberg, 2009-07-30 08:28:51

Vous pouvez utiliser Jasypt

Avec Jasypt, crypter et vérifier un mot de passe peut être aussi simple que...

StrongTextEncryptor textEncryptor = new StrongTextEncryptor();
textEncryptor.setPassword(myEncryptionPassword);

Cryptage:

String myEncryptedText = textEncryptor.encrypt(myText);

Décryptage:

String plainText = textEncryptor.decrypt(myEncryptedText);

Gradle:

compile group: 'org.jasypt', name: 'jasypt', version: '1.9.2'

Caractéristiques:

Jasypt vous fournit des techniques de chiffrement unidirectionnelles (digest) et bidirectionnelles faciles.

Ouvrez l'API pour une utilisation avec n'importe quel fournisseur JCE, et pas seulement la machine virtuelle Java par défaut. Jasypt peut être facilement utilisé avec des fournisseurs bien connus comme Bouncy Castle. En savoir plus.

Sécurité accrue pour les mots de passe de vos utilisateurs. En savoir plus.

Prise en charge du chiffrement binaire. Jasypt permet de digérer et de chiffrer des binaires (tableaux d'octets). Chiffrez vos objets ou fichiers en cas de besoin (pour être envoyés sur le net, par exemple).

Prise en charge du chiffrement des nombres. Outre les textes et les binaires, il permet de digérer et de chiffrer des valeurs numériques (BigInteger et BigDecimal, d'autres types numériques sont pris en charge lors du chiffrement pour la persistance Hibernate). En savoir plus.

Complètement thread-safe.

Prise en charge de la mise en commun de chiffreurs/digesteurs, afin d'obtenir des performances élevées dans les systèmes multi-processeurs/multi-cœurs.

Inclut une version allégée ("lite") de la bibliothèque pour une meilleure gestion dans les environnements restreignant la taille comme les plates-formes mobiles.

Fournit à la fois des outils de cryptage faciles et sans configuration pour les utilisateurs nouveaux cryptage, ainsi que des outils de cryptage standard hautement configurables, pour les utilisateurs expérimentés.

Hibernate 3 et 4 intégration facultative pour les champs persistants de vos entités mappées de manière cryptée. Le cryptage des champs est défini dans les fichiers de mappage Hibernate, et il reste transparent pour le reste de l'application (utile pour les données personnelles sensibles, les bases de données avec de nombreux utilisateurs en lecture...). Chiffrez les textes, les binaires, les nombres, les booléens, les dates... En savoir plus.

Parfaitement intégrable dans une application Spring, avec des fonctionnalités d'intégration spécifiques pour Spring 2, Spring 3.0 et Spring 3.1. Tous les digesteurs et chiffreurs de jasypt sont conçus pour être facilement utilisés (instanciés, injectés de dépendance...) à partir du printemps. Et, en raison de leur sécurité thread, ils peuvent être utilisés sans soucis de synchronisation dans un environnement orienté singleton comme Spring. En savoir plus: Printemps 2, Printemps 3.0, Printemps 3.1.

Sécurité printanière (anciennement Sécurité Acegi) intégration facultative pour effectuer le cryptage des mots de passe et les tâches de correspondance pour le cadre de sécurité, améliorer la sécurité des mots de passe de vos utilisateurs en utilisant des mécanismes de cryptage des mots de passe plus sûrs et vous fournir un degré plus élevé de configuration et de contrôle. En savoir plus.

Fournit des fonctionnalités avancées pour crypter tout ou partie des fichiers de configuration d'une application, y compris des informations sensibles telles que les mots de passe de base de données. Intégration transparente de la configuration cryptée dans des applications simples, basées sur Spring et/ou activées en veille prolongée. En savoir plus.

Fournit des outils CLI (Command Line Interface) faciles à utiliser pour permettre aux développeurs d'initialiser leurs données cryptées et d'inclure des opérations de cryptage/décryptage/synthèse dans les tâches de maintenance ou les scripts. En savoir plus.

S'intègre dans Apache Wicket, pour un cryptage plus robuste des URL dans vos applications sécurisées.

Guides complets et documentation javadoc, pour permettre aux développeurs de mieux comprendre ce qu'ils font vraiment à leurs données.

Prise en charge robuste des jeux de caractères, conçue pour chiffrer et digérer correctement les textes, quel que soit le jeu de caractères d'origine. Prise en charge complète des langues comme le Japonais, le Coréen, l'arabe... sans problèmes d'encodage ou de plate-forme.

Très haut niveau de capacités de configuration: Le développeur peut implémenter des astuces comme demander à un "chiffreur" de demander à un serveur HTTPS distant, par exemple, le mot de passe à utiliser pour le cryptage. Il vous permet de répondre à vos besoins de sécurité.

 3
Author: user3871754, 2018-04-07 01:46:58

Voici une solution simple avec seulement java.* et javax.crypto.* dépendances pour le chiffrement des octets fournissant confidentialité et intégrité. Il doit être indiscernable sous une attaque en texte clair choisie .

Il utilise AES dans le mode GCM sans remplissage, une clé 128 bits est dérivée par PBKDF2 avec beaucoup d'itérations et un sel statique à partir du mot de passe fourni. Cela garantit que le forçage brutal des mots de passe est difficile et distribue l'entropie sur l'ensemble clé.

Un vecteur d'initialisation aléatoire (IV) est généré et sera ajouté au texte chiffré. De plus, l'octet statique 0x01 est ajouté au début comme le premier octet en tant que "version".

Le message entier va dans le code d'authentification de message (MAC) généré par AES/GCM.

Ici, zéro classe de cryptage de dépendances externes fournissant confidentialité et intégrité:

package cryptor;

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * This class implements AES-GCM symmetric key encryption with a PBKDF2 derived password.
 * It provides confidentiality and integrity of the plaintext.
 *
 * @created 2018-02-25
 */
public class AesGcmCryptor {

    // https://crypto.stackexchange.com/questions/26783/ciphertext-and-tag-size-and-iv-transmission-with-aes-in-gcm-mode
    private static final byte VERSION_BYTE = 0x01;
    private static final int VERSION_BYTE_LENGTH = 1;
    private static final int AES_KEY_BITS_LENGTH = 128;
    private static final int GCM_IV_BYTES_LENGTH = 12;
    private static final int GCM_TAG_BYTES_LENGTH = 16;

    private static final int PBKDF2_ITERATIONS = 16384;

    private static final byte[] PBKDF2_SALT = hexStringToByteArray("4d3fe0d71d2abd2828e7a3196ea450d4");

    /**
     * Decrypts an AES-GCM encrypted ciphertext and is
     * the reverse operation of {@link AesGcmCryptor#encrypt(char[], byte[])}
     *
     * @param password   passphrase for decryption
     * @param ciphertext encrypted bytes
     *
     * @return plaintext bytes
     *
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchProviderException
     * @throws InvalidKeySpecException
     * @throws InvalidAlgorithmParameterException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws IllegalArgumentException           if the length or format of the ciphertext is bad
     */
    public byte[] decrypt(char[] password, byte[] ciphertext)
            throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException,
            InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException,
            BadVersionException {

        // input validation
        if (ciphertext == null) {
            throw new IllegalArgumentException("Ciphertext cannot be null.");
        }

        if (ciphertext.length <= VERSION_BYTE_LENGTH + GCM_IV_BYTES_LENGTH + GCM_TAG_BYTES_LENGTH) {
            throw new IllegalArgumentException("Ciphertext too short.");
        }

        // the version must match, we don't decrypt other versions
        if (ciphertext[0] != VERSION_BYTE) {
            throw new BadVersionException();
        }

        // input seems legit, lets decrypt and check integrity

        // derive key from password
        SecretKey key = deriveAesKey(password, PBKDF2_SALT, AES_KEY_BITS_LENGTH);

        // init cipher
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
        GCMParameterSpec params = new GCMParameterSpec(GCM_TAG_BYTES_LENGTH * 8,
                ciphertext,
                VERSION_BYTE_LENGTH,
                GCM_IV_BYTES_LENGTH
        );
        cipher.init(Cipher.DECRYPT_MODE, key, params);

        final int ciphertextOffset = VERSION_BYTE_LENGTH + GCM_IV_BYTES_LENGTH;

        // add version and IV to MAC
        cipher.updateAAD(ciphertext, 0, ciphertextOffset);

        // decipher and check MAC
        return cipher.doFinal(ciphertext, ciphertextOffset, ciphertext.length - ciphertextOffset);
    }

    /**
     * Encrypts a plaintext with a password.
     *
     * The encryption provides the following security properties:
     * Confidentiality + Integrity
     *
     * This is achieved my using the AES-GCM AEAD blockmode with a randomized IV.
     *
     * The tag is calculated over the version byte, the IV as well as the ciphertext.
     *
     * Finally the encrypted bytes have the following structure:
     * <pre>
     *          +-------------------------------------------------------------------+
     *          |         |               |                             |           |
     *          | version | IV bytes      | ciphertext bytes            |    tag    |
     *          |         |               |                             |           |
     *          +-------------------------------------------------------------------+
     * Length:     1B        12B            len(plaintext) bytes            16B
     * </pre>
     * Note: There is no padding required for AES-GCM, but this also implies that
     * the exact plaintext length is revealed.
     *
     * @param password  password to use for encryption
     * @param plaintext plaintext to encrypt
     *
     * @throws NoSuchAlgorithmException
     * @throws NoSuchProviderException
     * @throws NoSuchPaddingException
     * @throws InvalidAlgorithmParameterException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws InvalidKeySpecException
     */
    public byte[] encrypt(char[] password, byte[] plaintext)
            throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
            InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException,
            InvalidKeySpecException {

        // initialise random and generate IV (initialisation vector)
        SecretKey key = deriveAesKey(password, PBKDF2_SALT, AES_KEY_BITS_LENGTH);
        final byte[] iv = new byte[GCM_IV_BYTES_LENGTH];
        SecureRandom random = SecureRandom.getInstanceStrong();
        random.nextBytes(iv);

        // encrypt
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
        GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_BYTES_LENGTH * 8, iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, spec);

        // add IV to MAC
        final byte[] versionBytes = new byte[] { VERSION_BYTE };
        cipher.updateAAD(versionBytes);
        cipher.updateAAD(iv);

        // encrypt and MAC plaintext
        byte[] ciphertext = cipher.doFinal(plaintext);

        // prepend VERSION and IV to ciphertext
        byte[] encrypted = new byte[1 + GCM_IV_BYTES_LENGTH + ciphertext.length];
        int pos = 0;
        System.arraycopy(versionBytes, 0, encrypted, 0, VERSION_BYTE_LENGTH);
        pos += VERSION_BYTE_LENGTH;
        System.arraycopy(iv, 0, encrypted, pos, iv.length);
        pos += iv.length;
        System.arraycopy(ciphertext, 0, encrypted, pos, ciphertext.length);

        return encrypted;
    }

    /**
     * We derive a fixed length AES key with uniform entropy from a provided
     * passphrase. This is done with PBKDF2/HMAC256 with a fixed count
     * of iterations and a provided salt.
     *
     * @param password passphrase to derive key from
     * @param salt     salt for PBKDF2 if possible use a per-key salt, alternatively
     *                 a random constant salt is better than no salt.
     * @param keyLen   number of key bits to output
     *
     * @return a SecretKey for AES derived from a passphrase
     *
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    private SecretKey deriveAesKey(char[] password, byte[] salt, int keyLen)
            throws NoSuchAlgorithmException, InvalidKeySpecException {

        if (password == null || salt == null || keyLen <= 0) {
            throw new IllegalArgumentException();
        }
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec spec = new PBEKeySpec(password, salt, PBKDF2_ITERATIONS, keyLen);
        SecretKey pbeKey = factory.generateSecret(spec);

        return new SecretKeySpec(pbeKey.getEncoded(), "AES");
    }

    /**
     * Helper to convert hex strings to bytes.
     *
     * May be used to read bytes from constants.
     */
    private static byte[] hexStringToByteArray(String s) {

        if (s == null) {
            throw new IllegalArgumentException("Provided `null` string.");
        }

        int len = s.length();
        if (len % 2 != 0) {
            throw new IllegalArgumentException("Invalid length: " + len);
        }

        byte[] data = new byte[len / 2];
        for (int i = 0; i < len - 1; i += 2) {
            byte b = (byte) toHexDigit(s, i);
            b <<= 4;
            b |= toHexDigit(s, i + 1);
            data[i / 2] = b;
        }
        return data;
    }

    private static int toHexDigit(String s, int pos) {
        int d = Character.digit(s.charAt(pos), 16);
        if (d < 0) {
            throw new IllegalArgumentException("Cannot parse hex digit: " + s + " at " + pos);
        }
        return d;
    }
}

Voici l'ensemble du projet avec une belle CLI: https://github.com/trichner/tcrypt

 0
Author: trichner, 2018-02-28 17:07:27

C'est la méthode que j'ai utilisée.c'est simple mais il a une meilleure protection. https://github.com/chamikaras/simpleEncryptor

Lisez readme sur ce projet.C'est simple à utiliser.

public SimpleEncryptor(int MaximumLength) {
    //initialize encryption Key pattern variable
    pattern = new Integer[MaximumLength];
    //Generate pattern
    pattern =GenarateEncryptionPattern(MaximumLength);
}

private Integer[] GenarateEncryptionPattern(int Length) {
    Integer[] randomPattern = new Integer[Length];
    //generate encryption pattern
    for (int i = 0; i < Length; i++) {
        //make random encrypt key
        Random random = new Random();
        randomPattern[i] = random.nextInt(9);
    }
    return randomPattern;
}

public void simpleEncryptData(String data) {

    for (int i=0; i<data.length();i++){
        //get character from data
        char character = data.charAt(i);
        //convert character to ascii
        int ascii = (int) character;
        //decrypt data with random generated text
        int encryptedascii = ascii + pattern[i];
        //convert ascii to char
        char encryptedchar = (char)encryptedascii;
        //append string with char
        encryptedData += encryptedchar;

    }
}

private String convertKey(){
    //convert key to String
    String key = "";
    for (int i = 0;i<pattern.length;i++){
        key += String.valueOf(pattern[i]);
    }
  return key;
}


public String getDecryptData(String data, String key){
    String decryptedData = "";
    for (int i=0;i<data.length();i++){
        //get current key from decryptkey
        String number = key.substring(i,i+1);
        //get char from encrypeddata
        char encryptedchar = data.charAt(i);
        //convert char to ascii
        int encryptedascii = (char)encryptedchar;
        //decrypt encrypted char
        int decryptedascii = encryptedascii - Integer.valueOf(number);
        //convert ascii to char
        char decryptedchar = (char)decryptedascii;
        //append decrypted string
        decryptedData += decryptedchar;
    }
    return decryptedData;
}
public String getDecryptData(String data, Integer[] key){
    String decryptedData = "";
    for (int i=0;i<data.length();i++){
        //get char from encrypeddata
        char encryptedchar = data.charAt(i);
        //convert char to ascii
        int encryptedascii = (char)encryptedchar;
        //decrypt encrypted char
        int decryptedascii = encryptedascii - key[i];
        //convert ascii to char
        char decryptedchar = (char)decryptedascii;
        //append decrypted string
        decryptedData += decryptedchar;
    }
    return decryptedData;
}

public String getEncryptedData(){
    //return encryptedData
    return encryptedData;
}
public Integer[] getRawDecryptKey(){
    //return rawkey
    return pattern;
}
public String getStringDecryptKey(){
    //return string key
    return convertKey();
}

}

 0
Author: Chamikara, 2018-04-17 09:06:21

Comme beaucoup de gars l'ont déjà dit, vous devriez utiliser un chiffrement standard qui est trop utilisé comme DES ou AES.

Un exemple simple de la façon dont vous pouvez crypter et déchiffrer une chaîne en java en utilisant AES.

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class EncryptorDemo {

    public static String encrypt(String key, String randomVector, String value) {
        try {
            IvParameterSpec iv = new IvParameterSpec(randomVector.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(value.getBytes());
            System.out.println("encrypted text: "  + Base64.encodeBase64String(encrypted));
            return Base64.encodeBase64String(encrypted);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String decrypt(String key, String randomVector, String encrypted) {
        try {
            IvParameterSpec iv = new IvParameterSpec(randomVector.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] originalText = cipher.doFinal(Base64.decodeBase64(encrypted));
            System.out.println("decrypted text: "  + new String(originalText));
            return new String(originalText);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String key = "JavasEncryptDemo"; // 128 bit key
        String randomVector = "RandomJavaVector"; // 16 bytes IV
        decrypt(key, randomVector, encrypt(key, randomVector, "Anything you want to encrypt!"));

    }
}
 0
Author: viveknaskar, 2018-09-06 15:10:30
String s1="arshad"; 
char[] s2=s1.toCharArray(); 
int s3= s2.length; 

  System.out.println(s3);
 int i=0; 

// for(int j=0;j<s3;j++) 
// System.out.println(s2[j]); 

for(i=0;i<((s3)/2);i++) { 

char z,f=10; 
z=(char) (s2[i] * f); 
s2[i]=s2[(s3-1)-i]; 
s2[(s3-1)-i]=z; 

String b=new String(s2);

 print(b);  }
 -1
Author: Arshad shaik, 2017-09-01 18:38:47

Vous voudrez peut-être envisager un outil automatisé pour effectuer la génération de code de cryptage / décryptage, par exemple. https://www.stringencrypt.com/java-encryption/

Il peut générer un code de chiffrement et de déchiffrement différent à chaque fois pour le chiffrement de chaîne ou de fichier.

C'est assez pratique quand il s'agit de cryptage de chaîne rapide sans utiliser RSA, AES, etc.

Exemples de résultats:

// encrypted with https://www.stringencrypt.com (v1.1.0) [Java]
// szTest = "Encryption in Java!"
String szTest = "\u9E3F\uA60F\uAE07\uB61B\uBE1F\uC62B\uCE2D\uD611" +
                "\uDE03\uE5FF\uEEED\uF699\uFE3D\u071C\u0ED2\u1692" +
                "\u1E06\u26AE\u2EDC";

for (int iatwS = 0, qUJQG = 0; iatwS < 19; iatwS++)
{
        qUJQG = szTest.charAt(iatwS);
        qUJQG ++;
        qUJQG = ((qUJQG << 5) | ( (qUJQG & 0xFFFF) >> 11)) & 0xFFFF;
        qUJQG -= iatwS;
        qUJQG = (((qUJQG & 0xFFFF) >> 6) | (qUJQG << 10)) & 0xFFFF;
        qUJQG ^= iatwS;
        qUJQG -= iatwS;
        qUJQG = (((qUJQG & 0xFFFF) >> 3) | (qUJQG << 13)) & 0xFFFF;
        qUJQG ^= 0xFFFF;
        qUJQG ^= 0xB6EC;
        qUJQG = ((qUJQG << 8) | ( (qUJQG & 0xFFFF) >> 8)) & 0xFFFF;
        qUJQG --;
        qUJQG = (((qUJQG & 0xFFFF) >> 5) | (qUJQG << 11)) & 0xFFFF;
        qUJQG ++;
        qUJQG ^= 0xFFFF;
        qUJQG += iatwS;
        szTest = szTest.substring(0, iatwS) + (char)(qUJQG & 0xFFFF) + szTest.substring(iatwS + 1);
}

System.out.println(szTest);

Nous l'utilisons tout le temps dans notre entreprise.

 -2
Author: Bartosz Wójcik, 2015-10-26 18:51:25
public static String encryptParams(String myTextInput) {

        String myKey = "40674244454045cb9a70040a30e1c007";
        String myVector = "@1B2c3D4e5F6g7H8";

        String encData = "";

        try{
            JavaEncryprtionUtil encUtil = new JavaEncryprtionUtil();
            encData = Base64.encodeToString(encUtil.encrypt(myTextInput.getBytes("UTF-8"), myKey.getBytes("UTF-8"), myVector.getBytes("UTF-8")),Base64.DEFAULT);
            System.out.println(encData);
        }catch(NoSuchAlgorithmException ex){
            ex.printStackTrace();
        }catch(NoSuchPaddingException ex){
            ex.printStackTrace();
        }catch(InvalidKeyException ex){
            ex.printStackTrace();
        }catch(InvalidAlgorithmParameterException ex){
            ex.printStackTrace();
        }catch(IllegalBlockSizeException ex){
            ex.printStackTrace();
        }catch(BadPaddingException ex){
            ex.printStackTrace();
        }catch(UnsupportedEncodingException ex){
            ex.printStackTrace();
        }

        return encData;
    }
 -3
Author: rishikesh, 2014-04-24 19:36:21