Comment chiffrer une chaîne de caractères en Java

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

autres prescriptions:

  • ne devrait pas être compliqué
  • il ne devrait pas s'agir d'une infrastructure RSA, D'une infrastructure ICP, de paires de clés, etc.

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

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

que suggérez-vous? Y a-t-il une classe Java qui fait encrypt() encrypt() sans trop de complications pour atteindre une haute sécurité? les normes?

115
demandé sur Glenn 2009-07-30 12:13:10

15 réponses

je recommande d'utiliser un cypher symétrique standard qui est largement disponible comme DES , 3DES ou AES . Bien que ce ne soit pas l'algorithme le plus sûr, il y a beaucoup d'implémentations et vous avez juste besoin de donner la clé à n'importe qui qui est censé déchiffrer l'information dans le code à barres. javax.cryptographique.Crypter est ce que vous voulez travailler avec 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;

Maintenant vous pouvez initialiser le chiffre pour 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");

le 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 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
répondu 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 craquer donc je suis poster ceci pour ajouter des informations concernant le cryptage pour d'autres comme il a été 7 ans de la poste d'origine. Je détiens un Master en Informatique et a passé beaucoup de temps à étudier et à apprendre La cryptographie donc je jette mes deux cents pour faire de l'internet un endroit plus sûr.

aussi, notez que beaucoup de mise en œuvre pourrait être sécurisé pour un situation, mais pourquoi utiliser ceux et potentiellement accidentellement faire un erreur? Utiliser des outils les plus puissants disponibles, sauf si vous avez un raison spécifique de ne pas le faire. Dans l'ensemble, je recommande fortement l'utilisation d'une bibliothèque et rester à l'écart des détails croustillants, si vous le pouvez.

mise à jour 4/5/18: j'ai réécrit certaines parties pour les rendre plus simples pour comprendre et changer la bibliothèque recommandée de Jasypt à nouvelle bibliothèque de Google , je recommande de supprimer complètement Jasypt d'une configuration existante.

Avant-propos

je vais exposer 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 mettent en œuvre crypto sur leur propre avec la bibliothèque Java standard. Si vous voulez simplement sauter tous les détails, passez à la nouvelle bibliothèque de Google Tink importez cela dans votre projet et utilisez le mode AES-GCM pour tous vos cryptages 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 :)

Blocs D'Identification

première chose en premier vous devez choisir un clé symétrique de Chiffrement par Bloc. Un bloc de chiffrement est une fonction/programme informatique utilisé pour créer Pseudo-aléatoire. Le Pseudo-aléatoire est un faux aléatoire qu'aucun ordinateur autre qu'un ordinateur quantique ne pourrait distinguer du réel. Le chiffrement de bloc est comme le bloc de construction à la cryptographie, et lorsqu'il est utilisé avec des modes ou des schémas différents, nous pouvons créer des encryptions.

maintenant en ce qui concerne les Algorithmes de chiffrement de bloc disponibles aujourd'hui, assurez-vous de JAMAIS , je répète JAMAIS utiliser DES , je dirais même de ne JAMAIS utiliser de 3DES . Le seul chiffrement de bloc que même la version NSA de Snowden a pu vérifier en étant vraiment aussi proche que possible de Pseudo-aléatoire est AES 256 . Il existe aussi AES 128, la différence est AES 256 fonctionne dans les blocs de 256 bits, tandis que AES 128 fonctionne dans 128 blocs. En tout, AES 128 est considéré comme sûr, bien que certaines faiblesses ont été découvertes, mais 256 est aussi solide que possible.

Fun fact DES a été cassé par la NSA arrière quand il a été initialement fondé et réellement gardé un secret pendant quelques années et bien que certaines personnes prétendent toujours 3DES est sûr, il ya un bon nombre de documents de recherche qui ont trouvé et analysé des faiblesses dans 3DES .

Modes De Cryptage

cryptage est créé lorsque vous prenez un bloc de chiffrement et d'utiliser un schéma spécifique de sorte que le caractère aléatoire est combiné avec une clé pour créer quelque chose qui est réversible aussi longtemps que vous connaissez la clé. C'est ce Qu'on appelle un mode de chiffrement.

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

ECB Mode

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

ECB CTR, CBC, GCM

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é. JAMAIS utilisation de la BCE, c'est mauvais pour cacher des données répétitives comme le montre le célèbre penguin Linux . Linux Penguin Example

lors de la mise en œuvre en Java, notez que si vous utilisez le code suivant, le mode BCE est défini par défaut:

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

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

Nonces et IVs

en réponse à la question trouvée avec les noms de mode BCE également connu sous le nom IVs ont été créés. L'idée est que nous produisons une nouvelle variable aléatoire et l'attachons à chaque cryptage de sorte que lorsque vous cryptez deux messages qui sont les mêmes, ils sortent différents. La beauté derrière ceci est qu'une IV ou nonce est une connaissance publique. Que signifie un attaquant peut avoir accès à ce mais tant qu'ils n'ont pas votre clé, qu'ils ne peuvent pas faites n'importe quoi avec ce savoir.

les problèmes communs que je vais voir est que les gens vont définir L'IV comme une valeur statique comme dans la même valeur fixe dans leur code. et voici le piège pour IVs le moment où vous répétez un que vous compromettez réellement la sécurité entière de votre cryptage.

Génération Aléatoire IV

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

Note: SHA1 est cassé mais je ne pouvais pas trouver comment implémenter SHA256 dans ce cas d'utilisation correctement, donc si quelqu'un veut prendre un coup à cela et mettre à jour il serait génial! De plus, les attaques SHA1 ne sont toujours pas conventionnelles car il peut prendre quelques années sur un énorme cluster de se fissurer. voir les détails ici.

CTR mise en Œuvre

aucun rembourrage n'est requis pour le mode CTR.

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

SRC mise en Œuvre

si vous choisissez de mettre en œuvre le mode CBC faites-le avec PKCS7Padding comme suit:

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

vulnérabilité de CBC et CTR et pourquoi vous devriez utiliser GCM

bien que certains autres modes tels que CBC et CTR soient sécurisés, ils se retrouvent dans le problème où un attaquant peut retourner les données cryptées, en changeant leur valeur une fois déchiffrées. Alors disons que vous cryptez un message bancaire imaginaire "Sell 100", votre message crypté on dirait que ce " eu23ng "l'attaquant change un peu en" eu53ng "et tout d'un coup quand déchiffré votre message, il se lit comme"vendre 900".

pour éviter cela, la majorité de l'internet utilise GCM, et chaque fois que vous voyez HTTPS ils utilisent probablement GCM. GCM signe le message crypté avec un hachage et vérifie que le message n'a pas été changé en utilisant cette signature.

j'éviterais de mettre en œuvre le MCG en raison de sa complexité. Vous sont mieux à l'aide 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, qui est le défaut de sécurité ultime. Les nouveaux chercheurs travaillent vers des modes de cryptage à répétition IV où, même si vous répétez L'IV, la clé n'est pas en danger, mais ce n'est pas encore courant.

maintenant si vous voulez implémenter GCM, voici un lien vers un GCM sympa la mise en œuvre . Cependant, je ne peux pas assurer la sécurité ou si elle est correctement mise en œuvre, mais il obtient la base vers le bas. Notez aussi 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 quand 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 certain caractère aléatoire pour être considérée sécuriser. 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 fil StackOverflow pour la génération de clés aléatoire . 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ûre est d'utiliser, entrée utilisateur comme un mot de passe. La question dont nous avons discuté est que le mot de passe n'a pas assez d'entropie, donc nous devrions utiliser PBKDF2 , un algorithme qui prend le mot de passe et le renforce. Voici un StackOverflow mise en œuvre que j'ai aimé . Cependant, Google Tink bibliothèque a tout cela et vous devriez en profiter.

Développeurs Android

un point important pour souligner ici est de savoir que votre code android est moteur inverse et la plupart des cas code java est trop. Cela signifie que si vous stockez le mot de passe en texte clair dans votre code. Un pirate pourrait les récupérer facilement. Habituellement, pour ce type de cryptage, vous voulez utiliser la cryptographie asymétrique et ainsi de suite. Ceci est en dehors de la portée de ce post donc je vais éviter de plonger dans elle.

An intéressante lecture de 2013 : souligne que 88% de la Crypto les implémentations dans Android ont été faites incorrectement.

Réflexions

encore une fois , je suggère d'éviter d'implémenter la bibliothèque java pour la cryptographie directement et d'utiliser Google Tink , cela vous évitera les maux 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 sur les questions soulevées sur le Github Clochette, vulnérabilités popup ici et y.

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
répondu Konstantino Sparakis 2018-04-06 12:32:39

Avertissement

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

le mécanisme de cryptage de ce message est un tampon 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 la Base64Encoder/Decoder de Sun qui se trouve dans la JRE de Sun, pour éviter encore un autre bocal dans lib. C'est dangereux d'utiliser OpenJDK ou un autre JRE. En outre, 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
répondu ante.sabo 2016-05-31 11:46:42

merci j'ai fait cette classe en utilisant votre code peut-être que quelqu'un le trouve utile

objet crypter

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
répondu sherif 2010-09-18 18:59:19

Que pensez-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 très bien pour moi et est plutôt compact.

7
répondu yegor256 2012-12-26 15:59:34

Voici mon implémentation de meta64.com comme un Spring Singleton. Si vous voulez créer une instance de chiffrement pour chaque appel qui fonctionnerait aussi, et alors vous pourriez supprimer les appels 'synchronisés', mais attention 'cipher' n'est pas sûr pour le thread.

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
répondu mkobit 2015-08-03 18:17:37

j'envisagerais d'utiliser quelque chose comme https://www.bouncycastle.org / c'est une bibliothèque pré-compilée qui vous permet de crypter tout ce que vous voulez avec un certain nombre de chiffres différents Je comprends que vous ne voulez protéger de l'espionnage, mais si vous voulez vraiment protéger les informations, en utilisant Base64 ne sera pas réellement vous protéger.

4
répondu hdost 2015-01-06 21:26:08

voici quelques liens que vous pouvez lire ce que Java supporte""

chiffrement / déchiffrement d'un flux de données.

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

JCERefGuide

Java Exemples De Chiffrement

3
répondu Markus Lausberg 2009-07-30 08:28:51

vous pouvez utiliser Jasypt

avec Jasypt, chiffrer 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'

Dispose:

Jasypt vous offre des techniques de cryptage unidirectionnelles faciles (digest) et bidirectionnelles.

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

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

support de cryptage binaire. Jasypt permet le digest et cryptage des binaires (tableaux d'octets). Chiffrez vos objets ou fichiers lorsque nécessaire (pour être envoyé sur le net, par exemple).

support de chiffrement de numéro. Outre les textes et les binaires, il permet le digest et le cryptage des valeurs numériques (BigInteger et BigDecimal, d'autres types numériques sont pris en charge lors du cryptage pour la persistance Hibernée). En savoir plus.

entièrement sans fil.

prise en charge du crypteur / digesteur mise en commun, afin d'obtenir des performances élevées dans les systèmes multi-processeurs/multi-core.

comprend une version légère ("lite") de la bibliothèque pour une meilleure gérabilité dans des environnements restrictifs de taille comme les plateformes mobiles.

fournit à la fois des outils de cryptage faciles et sans configuration pour les utilisateurs débutants en cryptage, et des outils de cryptage standard hautement configurables pour les utilisateurs puissants.

hibernation 3 et 4 facultative intégration pour les champs persistants de vos entités cartographiées d'une manière cryptée. Le cryptage DES Champs est défini dans les fichiers de cartographie D'hibernation, et il reste transparent pour le reste de l'application (utile pour les données personnelles sensibles, bases de données avec de nombreux utilisateurs Lire-permise...). Chiffrez les textes, les binaires, les nombres, les booléens, les dates... En savoir plus.

parfaitement intégrable dans une application à ressort, avec des caractéristiques d'intégration spécifiques pour le ressort 2, Le ressort 3.0 et le ressort 5. Printemps 3.1. Tous les digesteurs et les crypteurs de jasypt sont conçus pour être facilement utilisés (instanciated, dependency-injected...) à partir du Printemps. Et, du fait de leur sécurité, ils peuvent être utilisés sans problème de synchronisation dans un environnement orienté singleton comme le printemps. En savoir plus: Printemps 2, Printemps 3.0, printemps 3.1.

Printemps de Sécurité (anciennement Acegi Security) en option d'intégration pour la réalisation de cryptage de mot de passe et correspondant à des tâches pour le cadre de la 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 plus haut degré de configuration et de contrôle. En savoir plus.

fournit la fonctionnalité avancée pour crypter tout ou partie des fichiers de configuration d'une application, y compris les informations sensibles comme les mots de passe de base de données. Intégrer de façon transparente la configuration chiffrée dans des applications simples, basées sur des ressorts et/ou compatibles avec L'hibernation. 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 chiffrement/déchiffrement/digestion dans les tâches ou les scripts de maintenance. En savoir plus.

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

guides complets et documentation javadoc, pour permettre aux développeurs de mieux comprendre ce qu'ils font réellement leurs données.

support robuste du jeu de caractères, conçu pour crypter et digérer adéquatement les textes, quel que soit le jeu de caractères original. Prise en charge complète de 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 mettre en œuvre des astuces telles que donner des instructions à un "encryptor" pour demander, par exemple, à un serveur HTTPS distant que le mot de passe soit utilisé pour le cryptage. Il vous permet de répondre à vos besoins de sécurité.

3
répondu user3871754 2018-04-07 01:46:58

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

il utilise AES dans le mode GCM sans rembourrage, une clé de 128bit est dérivé par PBKDF2 avec beaucoup d'itérations et un sel statique à partir de la le mot de passe. Cela permet de s'assurer que brute forçant les mots de passe est difficile et distribue l'entropie sur la clé entière.

un vecteur d'initialisation aléatoire (IV) est généré et sera prépendé au texte chiffré. De plus, le byte statique 0x01 est préprogrammé en tant que premier byte en tant que "version".

l'ensemble du message entre dans le code D'authentification du message (MAC) généré par AES/GCM .

voilà, zéro externe classe de cryptage des dépendances fournissant confidentiality et integrity :

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
répondu trichner 2018-02-28 17:07:27

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

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
répondu Chamikara 2018-04-17 09:06:21

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

un exemple simple de la façon dont vous pouvez chiffrer et déchiffrer une chaîne de caractères 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
répondu 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
répondu Arshad shaik 2017-09-01 18:38:47

vous pourriez vouloir envisager un outil automatisé pour faire le chiffrement / déchiffrement génération de code par exemple. https://www.stringencrypt.com/java-encryption /

il peut générer le cryptage et le code de décryptage différent à chaque fois pour la chaîne ou le cryptage de fichier.

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

résultats de L'échantillon:

// 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 société.

-2
répondu 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
répondu rishikesh 2014-04-24 19:36:21