Bonjour à tous.
Je travaille sur un problème de gestion de licence.
Le but ? Fournir à ceux qui auront payé une licence leur permettant d'utiliser un logiciel.
Bon, jusque là, c'est très commun. Le programme est un programme écrit en C++ donc compilé.
Le principe : encoder sur mon site web, la licence en RSA en utilisant la clef privée puis décoder cette clef avec la clef publique dans le logiciel.
Ok, plusieurs failles de sécurité : la clef de décodage est dans le programme (qu'il faudra masquer en l'encodant elle aussi pour ne pas la modifier facilement via un éditeur de texte).
Le but est simplement que l'on ne puisse pas facilement encoder une nouvelle licence... si on peut la lire c'est pas trop grave mais je ne veux pas pour autant la laisser en clair. De toute façon le système n'est pas fait pour être incassable car une protection logicielle est forcément faillible, il suffit de l'exécuter via un debugger... et avec de solides connaissances...
Le logiciel sera vendu certainement autour de 5€ (s'il sort un jour) donc je ne peux pas utiliser de dongle à 30€ pièce !
Voici mon problème :
-> cryptage RSA de la licence avec la clef privée sous PHP côté site web (la licence peut être décryptée sous php avec la clef publique).
-> décryptage impossible en utilisant OpenSSL.
wxmemDestinationBuffer est un wxMemoryBuffer (wxWidgets), c'est un simple buffer binaire qui contient la licence encryptée.
wxmemDestinationBuffer.GetDataLen() est ègal à RSA_size(pRSAPublicKey) (256)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 FILE *pfKeyFile = fopen("monchemin\\maclefpublique.pem", "r"); // Open the private key file RSA *pRSAPublicKey = PEM_read_RSA_PUBKEY(pfKeyFile, NULL, NULL, NULL); // And read the RSA key from it fclose(pfKeyFile); unsigned char *pszOutBuffer = new unsigned char[RSA_size(pRSAPublicKey)]; // Create some buffers of the right size int iLen = RSA_public_decrypt(wxmemDestinationBuffer.GetDataLen(), (const unsigned char *) wxmemDestinationBuffer.GetData(), pszOutBuffer, pRSAPublicKey, RSA_PKCS1_OAEP_PADDING);
iLen retourne toujours -1, le message d'erreur est "unknown padding type".
J'ai tenté avec RSA_PKCS1_PADDING, idem, le message est "block type is not 01"
Pour les puristes qui vont me répondre, normalement on crypte avec la clef publique et on décrypte avec la clef privée, mais je ne peux pas fournir une clef privée différente par utilisateur du logiciel !
Ce que je fais s'apparente plus à une signature numérique mais je souhaite aussi crypter la licence, qu'elle ne soit pas lisible en clair!
La question que je me pose : est-ce que OpenSSL PEUT décrypter avec la clef publique ? J'y ai passé des heures, modifier les options de cryptage côté php en CRYPT_RSA_ENCRYPTION_OAEP ou CRYPT_RSA_ENCRYPTION_PKCS1 mais rien n'y fait.
Si vous avez des réponses ou des suggestions...
-> il faut que la licence soit cryptée
-> Il ne faut pas que l'on puisse en générer par soi même
-> Il faut que je puisse authentifier / vérifier au décryptage que ça provient bien de moi
-> La licence générée fait 256 octets, il faut éviter qu'elle soit trop longue (genre signature numérique + hash + encryption + .... )
PS : j'ai aussi essayé RSA_private_decrypt() mais là, c'est pire, le programme crash (segmentation fault).
Partager