-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature request] option to encrypt without obfuscation #1
Comments
Hi, Thank you for using my tool, I'm glad you find it useful! Also thanks for your feedback and your request to improve it. Regarding the feature request, I would like to know what problems it is causing exactly. Please could you post a couple of examples of things Codeclose should not obfuscate? The fragment of the original source code and the result would be very useful to me. Thanks! EDIT: just to clarify, using external attributes and functions shouldn't be a problem. Codeclose only replaces identifiers that are defined or assigned, but not only read. |
Well, I had to change my scripts, folders structure etc. to test the obfuscation again.
It is quite difficult for me to find what is causing issues as I cannot set break points in my Dev environment. I have to rely on tracing (logs) which are useless with obfuscation. Which is another plus in my opinion for encryption. Today - with full obfuscation - I reached a point where I was able to launch the application and get the login screen but not beyond. In the logs I can see in which module the application stops but I have no idea what is going on. And I get nowhere with obfuscation light as it requires me to change code in many places to solve import issues. I will continue debugging tomorrow and let you know. Error stack:
|
Good to know. Thank you! |
Many thanks for the report! I created 3 new issues to address them. I will try to fix them ASAP. After that I will add two new options: |
Thank you! |
Hi! I just fixed all the reported bugs, plus added a new option I'm considering not implementing Please, let me know if that works for you ;) Ref: 2304940 |
Hi! Thank you, that was quick. I tested the new code today - although not the disable obfuscation option - and have a few observations.
I will make additional tests and let you know. |
Thanks for the report! I've been checking the new cases.
Please let me know if you find something else! |
Hi! I have been busy these last days updating my environments to python3.8 (from python3.7) only to find out that codeclose is not compatible with python3.8 The issue is due to errors in astunparse library. Full error stack below. For more information on the issue, please visit this page (read until the end): simonpercivall/astunparse#43 Now I am busy reverting to python3.7.5 and will give you a feedback about your latest changes shortly.
|
Hi! Good news! Not everything is working as I still have to exclude some identifiers here and there and refactor the code where needed, but it almost done. Thank you! The only thing left (in my opinion) is the python3.8+ bug I described earlier. I need to upgrade to python3.8 unfortunately. Again thank you. If if find anything else I will let you know. Still testing the application. |
Hi! I'm glad it works! I will check the Python 3.8 issue. Maybe I can replace the constant by something else in the tree before running astunparse. Thanks!! |
Hi Laurent, Happy new year! Sorry for the delay, I was a little bit busy during the holidays. I'm trying to reproduce the problem in Python 3.8.7, but I can't find a way of making it crash. I thought it was as simple as writing a Please could you give me an example of code that makes the system crash? |
Hi Juan, I was not aware you posted this last comment! Just saw it now, almost two months later... So you do not have the issue on Python 3..8.7 ? I am using Python 3.8.5 I will test again with Python 3.8.5 and then Python 3.8.7 and let you know. Thank you for your efforts. Your project is very helpful to me. Laurent. |
Hi! @juanlao7 I am not able to reproduce the "constant" error either, at least for now. The code has substantially changed since last December and that could be the reason. But I cannot reach a definitive conclusion as I am facing new issues that prevent me from using the obfuscated application. Codeclose options used for the sample code below are:
Code: tmp_dict = {'name': 'value'}
tmp_dict2 = tmp_dict.copy()
tmp_lst = ['one', 'two']
tmp_lst.sort() Obfuscation: tmp_dict_25250 = {'name': 'value'}
tmp_dict2_55191 = tmp_dict_25250.copy_42835()
tmp_lst_98502 = ['one', 'two']
tmp_lst_98502.sort_21163() Errors
I am not sure I had these issues before the last Codeclose code change. But I could be wrong. It was almost two months ago. Thank you for your help. Laurent. |
Hello Laurent, This is weird, I can't reproduce that problem either. I committed a new example case similar to yours. You can compile it by just running I tried to manually use the same arguments you are using and it still works. I am using Python 3.8.7 on Windows. Does that example case work for you? |
Hi @juanlao7 Sorry for the delayed answer. The good news is I managed to get the (full) obfuscation working on my project. Unfortunately the encryption does not work anymore. Here are some findings and workarounds I want to share. 1) Test with Example7
2) Solution to the attribute error tmp_dict_25250 = {'name': 'value'}
tmp_dict2_55191 = tmp_dict_25250.copy_42835()
tmp_lst_98502 = ['one', 'two']
tmp_lst_98502.sort_21163() were due to having somewhere else in my code: import copy
...
sort = "df = df....." which was obfuscated as:
what it means is if you have an import or variable which as the same name as an identifier's attribute you will get the result above, even if you try to avoid it using --keep-identifier and --keep-attributes flags. 3) Astunparse issue
The workaround I found was to downgrade to version 1.6.2 from 1.6.3 which is automatically installed as a dependency of codeclose:
Which makes me wonder if this is why you are not getting the error. Are you using version 1.6.2? 4) Encryption
Which seems to happen here (in runtime.py): cipher = AES.new(license['encryptingKey'], AES.MODE_CBC, iv=b64decode(initializationVector))
contentBytes = cipher.decrypt(b64decode(encryptedContent)) I have tried to encrypt with any combination of the following flags (--disable-string-obfuscation, --name-obfuscation light) without success. 5) Suggestion StopIteration_RecursionError(verifyingPublicKey=lc, encryptingKey=mu, expectedProductIds=[2], productKey=st) maybe we could use something like this? StopIteration_RecursionError(vp=lc, ek=mu, prd=[2], kp=st) 6) Thank you I saw somewhere in your code that a license server can be used. If it is not too difficult and you can guide me with the implementation I might try to do it in the future (in a month or so) as my code runs in a container and a license server is recommended. Thanks! |
Hi Laurent! Thank you very much for your feedback, it is really useful for finding and fixing the cause of the problems. I am glad Codeclose is useful for you!
Seems that this problem doesn't occur on Windows (Python 3.8.7, Astunparse 1.6.3). However, I could reproduce it on Linux (Python 3.8.4, Astunparse 1.6.3). Since Astunparse won't fix the issue, I made a workaround and fixed the problem in commit 0f145f5 Please, let me know if you can still reproduce the problem.
I am trying to reproduce the problem, but everything works fine in my environment. I committed a new example case similar to your case. You can compile it by just running This is the source code: # Example to reproduce https://github.com/juanlao7/codeclose/issues/1#issuecomment-814175447
# These identifiers should be obfuscated.
import copy
sort = 1
# But the attributes of this object should be kept.
attributesKept = [2, 1]
attributesKept.copy()
attributesKept.sort() And this is the obfuscated result: import copy as IsADirectoryError_ReferenceError
break_compile = 1
attributesKept = [2, 1]
attributesKept.copy()
attributesKept.sort() I think the problem in your case is that the identifiers
Seems that the problem is that, after decrypting one of your files, Python cannot convert the decrypted bytes into an UTF-8 string because the first character/byte is If none of your source files contain this character, then the problem may be that, by mistake, you are trying to decrypt with a different encryption key than the one you used for encrypting. Can that be the case? If that's not the case, I would really appreciate if you could send me a little example of code that triggers this problem, so I can look into it.
Thanks for the feedback! I just fixed it in commit 901dd52 However, take into account that Codeclose does not obfuscate keyword arguments (a.k.a. kwargs), because usually the function access them by the string key (e.g., If you want to obfuscate the parameters passed to configure(productKey, verifyingPublicKey, encryptingKey, expectedProductIds)
I guess you are referring to # TODO: obtain the license from the remote server At this moment the license is being computed locally, and that's why you need to store and provide the verifying public key and the encrypting key. This allows you to validate product keys offline, without requiring an internet connection. However, this is a weak point for Codeclose, because someone can debug your app to extract the encrypting key and decrypt all your code. My plan was to implement some kind of optional online validation. Instead of configuring Codeclose with the verifying and the encrypting key, you could configure it with the URL of a validating server, and then Codeclose would make an HTTP request to send the product key. If the product key is valid, the server would respond with the encrypting key, and then Codeclose would be able to decrypt and run all the code. The bad news is that this feature is not implemented right now (and unfortunately I don't have plans to implement it in the short term). The good news is that you can implement a similar system independently of Codeclose:
I hope this helps! |
Hi,
First of all thank you for your great work and your decision to publish that work so that the community can benefit from it.
I think it would be beneficial to have an option to not obfuscate some files similar to what we have with encryption exclusions.
Here's why.
In my particular scenario, I have a lot of modules/classes that use many third parties modules. Which means I end up with an extremely long list of identifiers/attributes to exclude. I have tried to obfuscate my entire application without success. In my case it is a daunting task.
Even if I succeeded, it would be difficult to maintain such a list with an application that gets updated constantly.
In contrast, encryption only requires a small effort to implement, and is not dependent on code change. And the performance is also great.
As a workaround, I changed the code to only obfuscate the application entry point (main.py) and encrypt the remaining files.
In model.py:
But I am facing two caveats with that workaround:
This is the only notable difference I can see that sets it apart from other files.
Here are the details of the error:
I think the error happens here (in runtime.py)
I am not sure how to fix such an error but again thank you for letting us use your code.
The text was updated successfully, but these errors were encountered: