Bonjour à tous. J'ai developpé une application java et j'aimerais la proteger par une licence qui doit être renouvellé chaque année. Comment je peux faire cela?
Merci d'avance.
Bonjour à tous. J'ai developpé une application java et j'aimerais la proteger par une licence qui doit être renouvellé chaque année. Comment je peux faire cela?
Merci d'avance.
La force d'un programmeur ne réside pas dans le fait qu'il écrive des codes puissants mais dans sa capacité à les maintenir!!!
En faisant en sorte que ton application ne marche qu'avec un accès Internet, et qu'elle doive se connecter à ton serveur pour marcher (et que ton serveur fasse un travail utile de sorte que modifier l'application ne permette pas de se passer du serveur.)
Le serveur connaît donc l'ensemble des licences valides, et si une application essaie de tourner sans licence ou avec une licence invalide ou expirée, le serveur refuse de lui répondre et elle ne marche pas.
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
Il y a de multiples possibilités. Tout dépend du temps, de l'argent et du matériel que tu souhaites y consacrer.
Une autre possibilité : le logiciel vérifie la date système. Si c'est plus d'un an après le début de licence, il s'arrête.
Tu vas me dire qu'il suffit de modifier l'heure du PC pour que le logiciel fonctionne. Et c'est là que mes deux premières phrases prennent tout leur sens ;-)
Sache seulement ceci : quelque soit la solution choisie, il y aura toujours une méthode pour contourner la licence. Elle demandera du temps et/ou de l'argent et/ou du matériel de manière plus ou moins importante, mais ce sera toujours possible.
Tout l'exercice consiste à ce que toi, tu dépenses assez de temps/argent/matériel pour que ce ne soit pas très rentable pour le cracker et qu'il préfère acheter ta licence.
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
Que la force de la puissance soit avec le courage de ta sagesse.
Ma méthode est certes très contraignante, mais avec elle, la seule solution de contournement est de refaire l'application soi-même au lieu de prendre une licence.
Les autres méthodes, ce qui est gênant n'est pas que ce soit possible, mais que ce soit facile. L'élégance de Java a un prix, ce prix est qu'il est facile de modifier sa structure et de patcher les programmes faits avec. Il existe quelques systèmes visant à "protéger" des programmes Java, mais ou bien ce qu'ils protègent est sans intérêt, ou bien ils ne sont pas assez nombreux et il y a des méthodes connues pour contourner chacun d'entre eux.
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
De plus c'est une application pour une entreprise et les états porte le nom de la structure. donc je veux un système juste pour la verification de la licence en fonction de la date.
La force d'un programmeur ne réside pas dans le fait qu'il écrive des codes puissants mais dans sa capacité à les maintenir!!!
Si c'est pour un truc aussi simple que ça, c'est d'un niveau débutant. Je ne pense pas que tu trouveras une bibliothèque qui s'en occupe à ta place.
La seule chose à décider, c'est où est enregistrée la date d'expiration de la licence. C'est une décision qui te concerne toi et que personne ne prendra à ta place.
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
Au bout de quelques heures de recherche j'ai entendu parlé d'un principe que je voudrais implémenter. Il est simple j'enregistre un fichier qui possède le licence qui est la concaténation d'une chaine de caractère et la date d'expiration. A chaque fois qu'un utilisateur se connecte on vérifie si la licence est toujours valide en fonction de la date courante. Le plus dur pour moi est de crypter/décrypter le fichier car pour des soucis de sécurité j'aimerais crypter le fichier avant de le stocker sur la machine serveur (machine qui contient la BD).
J'ai fait des recherches et je suis tombé sur la classe suivante:
Maintenant j'aimerais savoir:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 package tp; //Updates: 2004.03.23 import java.math.*; import java.security.*; import java.security.spec.*; import java.security.interfaces.*; /** * Cette classe propose des méthodes permettant de crypter et décrypter des * messages avec l'algorithme RSA. Le message doit cependant être plus petit * que KEY_SIZE. */ public class MyRSA { public final static int KEY_SIZE = 512; // [512..2048] private RSAPublicKey publicKey; private RSAPrivateKey privateKey; public MyRSA() { } public RSAPublicKey getPublicKey() { return publicKey; } public byte[] getPublicKeyInBytes() { return publicKey.getEncoded(); } public RSAPrivateKey getPrivateKey() { return privateKey; } public byte[] getPrivateKeyInBytes() { return privateKey.getEncoded(); } public void setPublicKey(RSAPublicKey publicKey) { this.publicKey = publicKey; } public void setPublicKey(byte[] publicKeyData) { try { X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyData); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); publicKey = (RSAPublicKey)keyFactory.generatePublic(publicKeySpec); } catch (Exception e) {System.out.println(e);} } public void setPrivateKey(RSAPrivateKey privateKey) { this.privateKey = privateKey; } public void setPrivateKey(byte[] privateKeyData) { try { PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyData); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); privateKey = (RSAPrivateKey)keyFactory.generatePrivate(privateKeySpec); } catch (Exception e) {System.out.println(e);} } public void generateKeyPair() { try { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); keyPairGen.initialize(KEY_SIZE, new SecureRandom()); KeyPair kp = keyPairGen.generateKeyPair(); publicKey = (RSAPublicKey)kp.getPublic(); privateKey = (RSAPrivateKey)kp.getPrivate(); } catch (Exception e) {System.out.println(e);} } public byte[] crypt(byte[] plaintext) { return crypt(new BigInteger(addOneByte(plaintext))).toByteArray(); } public byte[] crypt(String plaintext) { return crypt(plaintext.getBytes()); } public byte[] decryptInBytes(byte[] ciphertext) { return removeOneByte(decrypt(new BigInteger(ciphertext)).toByteArray()); } public String decryptInString(byte[] ciphertext) { return new String(decryptInBytes(ciphertext)); } /** * Cette méthode permet de tester le bon fonctionnement des autres. */ public static void main(String[] args) { String plaintext = "toto"; System.out.println("plaintext = " + plaintext); MyRSA rsa = new MyRSA(); rsa.generateKeyPair(); byte[] publicKey = rsa.getPublicKeyInBytes(); byte[] privateKey = rsa.getPrivateKeyInBytes(); byte[] ciphertext = rsa.crypt(plaintext); System.out.println("ciphertext = " + new BigInteger(ciphertext)); System.out.println("Le mot crypté est: "+ciphertext.toString()); rsa.setPublicKey(publicKey); rsa.setPrivateKey(privateKey); String plaintext2 = rsa.decryptInString(ciphertext); System.out.println("plaintext2 = " + plaintext2); if (!plaintext2.equals(plaintext)) System.out.println("Error: plaintext2 != plaintext"); } private BigInteger crypt(BigInteger plaintext) { return plaintext.modPow(publicKey.getPublicExponent(), publicKey.getModulus()); } private BigInteger decrypt(BigInteger ciphertext) { return ciphertext.modPow(privateKey.getPrivateExponent(), privateKey.getModulus()); } /** * Ajoute un byte de valeur 1 au début du message afin d'éviter que ce dernier * ne corresponde pas à un nombre négatif lorsqu'il sera transformé en * BigInteger. */ private static byte[] addOneByte(byte[] input) { byte[] result = new byte[input.length+1]; result[0] = 1; for (int i = 0; i < input.length; i++) { result[i+1] = input[i]; } return result; } /** * Retire le byte ajouté par la méthode addOneByte. */ private static byte[] removeOneByte(byte[] input) { byte[] result = new byte[input.length-1]; for (int i = 0; i < result.length; i++) { result[i] = input[i+1]; } return result; } }
Comment sauvegarder une clé que j'utilise pour crypter le fichier pour le décryptage lors de la connexion d'un utilisateur?
Si le dit fichier de licence est sur le serveur, comment le lire sans utiliser le protocole ftp ou http?
La force d'un programmeur ne réside pas dans le fait qu'il écrive des codes puissants mais dans sa capacité à les maintenir!!!
Bonjour,
C'est une solution qui fonctionne bien, mais qui ne résistera pas très longtemps en java.
Comme dit plus haut, c'est une histoire de temps et d'argent pour protéger une application.
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
Quelle solution me proposez-vous donc?
La force d'un programmeur ne réside pas dans le fait qu'il écrive des codes puissants mais dans sa capacité à les maintenir!!!
Mais elle est très bien cette solution, si tu en es content. Elle est facile à contourner parce que ce sera toujours facile à contourner, c'est tout.
Si tu veux pas que ça le soit, je t'ai déjà dit comment faire. Tu veux pas de connexion Internet eh ben t'en auras une quand même. (Alternative : fournir une boîte USB avec chaque licence. Cette boîte contient une copie de la licence et communique avec l'appli pour vérifier qu'elle est valide, et s'occupe de faire un travail important que l'appli ne fait pas. Bref elle remplace un serveur sur Internet. C'est cher et contraignant mais ça marche.)
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
Pourquoi serait-elle facile à contourner? J'aimerais tout de même continuer avec mon approche pouvez-vous m'aider?
La force d'un programmeur ne réside pas dans le fait qu'il écrive des codes puissants mais dans sa capacité à les maintenir!!!
Car il suffit en java de contourner ta classe de vérification.
La conception d'une solution de licence efficace requière comme expliqué du temps et donc de l'argent.
Ce n'est pas le but du forum de fournir des solutions toutes faites.
Moi je te conseil plutôt de multiplier les vérifications partout dans ton code de manière différente et d'obfusquer un minimum.
Ca rendra le boulot plus long et donc moins intéressant pour un attaquant.
En l'occurrence, le problème est plutôt que les seules solutions qui auraient un peu d'efficacité, dénatureraient tellement l'architecture Java que ça n'aurait plus aucun intérêt d'avoir programmé l'appli en Java.
À ce niveau-là il vaut mieux programmer en C++. Il n'y a pas d'introspection, l'architecture cible est un processeur x86 abominablement sale, et déplomber ça commence à demander un certain niveau de talent.
En l'occurrence on en aurait de toute façon pas à donner...
On va pas prendre ses décisions à sa place : où faut-il planquer la clé ? Mais on en a aucune idée mon grand, où tu veux et peux !
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
Je ne comprends pas bien quand tu me demande de vérifier de manière moi je pensais que je devais juste lire la clé, décrypter le fichier et lire les données en faisant des tests pour savoir si la licence est valide. De plus comment je fait pour crypter le fichier je dois d'abord le lire dans une variable(String) avant de crypter?
La force d'un programmeur ne réside pas dans le fait qu'il écrive des codes puissants mais dans sa capacité à les maintenir!!!
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager