Skip to content
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

fix(weaver): usage of weak PRNG issue #2907

Merged
merged 1 commit into from
Dec 5, 2023

Conversation

KaganCanSit
Copy link
Contributor

@KaganCanSit KaganCanSit commented Nov 25, 2023

The Logic Behind the Problem
When RNG (Random Number Generator) values are not received through a hardware TRNG, seed values apply a certain pattern. (It takes a seed value such as a mathematical formula or time.) In response to this situation, there are various secure random classes to increase security.

Solution
Changes have been made to get random values using safe randomness instead of mathematical randomness. This increases the complexity of the pattern, making it difficult to discover even if data is listened to for long periods of time.

The changes that have been made;

  • In the "certificate_utils.go" file, the random value was taken from the math class (mrand "math/rand") and used. By taking this random value from the secure random class, we obtain a more reliable random value. I added HmacGenerate and generateSecureRandomKey functions for readability and ease of use. If you want to generate a key again, the generateSecureRandomKey function, which uses secure random, can be used.

  • In "HashFunctions.kt", kotlin.random.Random class has been replaced with the more reliable java.security.SecureRandom class.

  • The reason for the change in "eciesCrypto.js" is that the length of aes-128-ctr is not considered reliable by various standards. For this reason, I preferred the more reliable 256 length.

Fixes #2765

Pull Request Requirements

  • [☑] Rebased onto upstream/main branch and squashed into single commit to help maintainers review it more efficient and to avoid spaghetti git commit graphs that obfuscate which commit did exactly what change, when and, why.

  • [☑] Have git sign off at the end of commit message to avoid being marked red. You can add -s flag when using git commit command. You may refer to this link for more information.

  • [ ] Follow the Commit Linting specification. You may refer to this link for more information.

Character Limit

  • [☑] Pull Request Title and Commit Subject must not exceed 72 characters (including spaces and special characters).
  • Commit Message per line must not exceed 80 characters (including spaces and special characters).

A Must Read for Beginners
For rebasing and squashing, here's a must read guide for beginners.

@KaganCanSit
Copy link
Contributor Author

KaganCanSit commented Nov 25, 2023

Hello,
The current problem and locations are well defined.(#2765) I'm a C++ developer myself. But I wanted to try myself to solve this problem. Since I am not an expert in Go, I made changes using various sources. However, I do not have time to create and execute the project as a whole. I examined the files one by one, taking into account their compilation status.

If there is an easy way I can test it or if we can create the environment in a short time, I can make additional arrangements. Please check the current status when you are available.

I'm just getting into the Open Source world. I can do my best as long as I have the opportunity.
See you later.

Some of the resources I used are;
https://stackoverflow.com/questions/32349807/how-can-i-generate-a-random-int-using-the-crypto-rand-package
https://pkg.go.dev/crypto/rand
https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html
https://serverfault.com/questions/51895/are-128-and-256bit-aes-encryption-considered-weak

@KaganCanSit KaganCanSit force-pushed the main branch 6 times, most recently from 7a877c2 to bacf6f4 Compare November 27, 2023 17:50
Copy link
Contributor

@petermetz petermetz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KaganCanSit Thank you very much for the detailed explanation and the context! Welcome on-board to our list of contributors!

If you ever have any more questions about contributing, we have daily pair programming call [1] that runs at 10 AM Pacific Time on most weekdays on our discord channel.

To answer your specific question as well and also give some tips, here's what I just did to figure out how to test the changes you made to certificate_utils.go

  1. I did a full text search in VSCode to go build which gave me a long list of hits
  2. I found the first file that was a match to my search that also had the right path [2] as in, the go build runs in the directory where you changed the code.
  3. From then on, I saw that the .github/workflows/test_weaver-go.yaml contains what I need in terms of reproducing the test cases as they are executed on the CI
  4. So what I did then is checked out your PR's branch in git and then ran these commands (basically just replaying what the github action in the .yml does)
  5. cd weaver/core/network/fabric-interop-cc/contracts/interop
  6. go build -v ./...
  7. go test -v ./...
  8. The output of the test indicated that all the tests passed.
  9. Based on all the above, I think this is looking good.

[1] https://wiki.hyperledger.org/display/cactus/Daily+Pair+Programming+Calls
[2] image

Copy link
Contributor

@petermetz petermetz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KaganCanSit Sorry, a few more things in terms of administrative details:

  1. Please make sure to explain in the commit message thoroughly the what/why/how (weak encryption as the root cause is kinda self explanatory but the specific solution could be explained a little further so that everyone is on the same page about it for sure)
  2. Please use the Fixes #??? syntax in your commit message to indicate the issue number that you are fixing. It has to be exactly this way because then the bots pick it up and auto-close the issue that you are fixing the moment the pull request is merged (more automation makes it easier for the maintainers to review a higher number of pull requests and keeps everyone a little happier in general)

If you need any help with these things, especially the git related things, feel free to reach out for help here or in the pair programming calls that I was talking about in my previous comment as well.

@KaganCanSit KaganCanSit changed the title fix(weaver): usage of weak PRNG #2765 issue - Solve fix(weaver): usage of weak PRNG issue Dec 2, 2023
@KaganCanSit
Copy link
Contributor Author

@petermetz Thanks for the information you shared with me. I tried to explain the logic of the error and why I made the change as briefly as I could. I included the error code in my message in the required format. If there is any content you would like me to edit, please write. I will deal with it at my first available time.

@KaganCanSit KaganCanSit requested a review from petermetz December 2, 2023 07:46
Copy link
Contributor

@petermetz petermetz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KaganCanSit You were editing it only in one place but it has to be done in two places (unfortunately the way GitHub works for some reason).
You need to amend the git commit message (right side of screenshot) with the same content you put in the pull request description (left side of the screenshot).

The reason behind this is that the pull request description is something that is stored in a proprietary database that we don't have full access to (GitHub's own servers) whereas the git log is something that is native to git itself and should we ever end up migrating away from GitHub to a different platform we could do so knowing that the important historical context of the changes we've made can be found in the git log, not just the database powering the website called github.com

image

@KaganCanSit KaganCanSit force-pushed the main branch 3 times, most recently from a99c681 to 1102e7b Compare December 2, 2023 20:05
@KaganCanSit
Copy link
Contributor Author

@petermetz Sory,I should have remembered to amend the commit message. It seems okay now.

@KaganCanSit KaganCanSit requested a review from petermetz December 2, 2023 20:07
Copy link
Contributor

@petermetz petermetz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KaganCanSit No worries. LGTM!

The Logic Behind the Problem
When RNG (Random Number Generator) values are not received through a hardware TRNG, seed values apply a certain pattern. (It takes a seed value such as a mathematical formula or time.) In response to this situation, there are various secure random classes to increase security.

Solution
Changes have been made to get random values using safe randomness instead of mathematical randomness. This increases the complexity of the pattern, making it difficult to discover even if data is listened to for long periods of time.

The changes that have been made;
- In the certificate_utils.go file, the random value was taken from the math class (mrand math/rand) and used. By taking this random value from the secure random class, we obtain a more reliable random value. I added HmacGenerate and generateSecureRandomKey functions for readability and ease of use. If you want to generate a key again, the generateSecureRandomKey function, which uses secure random, can be used.

- In HashFunctions.kt, kotlin.random.Random class has been replaced with the more reliable java.security.SecureRandom class.

- The reason for the change in eciesCrypto.js is that the length of aes-128-ctr is not considered reliable by various standards. For this reason, I preferred the more reliable 256 length.

Fixes hyperledger-cacti#2765

Signed-off-by: Kağan Can Şit <[email protected]>
@petermetz petermetz merged commit fa17b52 into hyperledger-cacti:main Dec 5, 2023
91 of 134 checks passed
@VRamakrishna
Copy link
Contributor

@KaganCanSit One of the changes made in this PR was incorrect, causing the code to fail. The unit test for that module would have caught the error but was disabled.

Can you please work on a fix ASAP? I've added appropriate comments against the offending change.

@petermetz @sandeepnRES FYI.

@VRamakrishna
Copy link
Contributor

@KaganCanSit

The reason for the change in "eciesCrypto.js" is that the length of aes-128-ctr is not considered reliable by various standards

Can you point to a source for this? I need to understand the implications. Per my understanding, 128 bits for AES is still highly secure. (But my knowledge could be outdated.)

@VRamakrishna
Copy link
Contributor

I checked with a cryptography expert and he informed me that 128-bit AES is secure enough for classical computers but is quantum-unsafe. To be quantum-safe, we do need to upgrade to 256 bits.

@KaganCanSit
Copy link
Contributor Author

Hello @VRamakrishna,

First of all, I would like to help you and learn something new as soon as possible. Since this is my first contribution to this project, I may have missed some parts.

I would like to start by explaining as best I remember why I changed the AES-128 length to AES-256. When I examined the content of the opened issue (https://github.com/hyperledger/cacti/issues/2765), I saw that mostly the random seed values were not from reliable sources. Basically, the first two parts mentioned were like this. However, the "crypto" class was used in the "weaver/sdks/fabric/interoperation-node-sdk/src/eciesCrypto.js" file and was specified as weak. When I examined various sources, I thought that the AES-128-CTR key was mentioned as the part that needed to be replaced. This was the first idea that led me to increasing the key length.

I took a look at various contents. Basically, in many sources, the length of 128 is considered sufficient, as you said. Including in banking. (https://www.pcisecuritystandards.org/glossary/strong-cryptography/)

In other cases, there is information that it was increased as a precaution against Quantom computers and military content. They think it would be better to use 256 to preserve data over time.(https://crypto.stackexchange.com/questions/76738/has-aes-128-been-complete-broken/76746#76746,
https://web.archive.org/web/20160306104007/http://research.microsoft.com/en-us/projects/cryptanaliz/aesbc.pdf) It is important how long the data will remain useful. Essentially, the situation is that the key takes longer to break. Here it may be better to determine how long the key will serve and its security level. Of course, I might have misunderstood the error at first glance.

Since I'm a C++ developer, I was a little hesitant about this pr. For testing I relied on the build states and tests on the path @petermetz outlined for me.

@KaganCanSit Thank you very much for the detailed explanation and the context! Welcome on-board to our list of contributors!

If you ever have any more questions about contributing, we have daily pair programming call [1] that runs at 10 AM Pacific Time on most weekdays on our discord channel.

To answer your specific question as well and also give some tips, here's what I just did to figure out how to test the changes you made to certificate_utils.go

  1. I did a full text search in VSCode to go build which gave me a long list of hits
  2. I found the first file that was a match to my search that also had the right path [2] as in, the go build runs in the directory where you changed the code.
  3. From then on, I saw that the .github/workflows/test_weaver-go.yaml contains what I need in terms of reproducing the test cases as they are executed on the CI
  4. So what I did then is checked out your PR's branch in git and then ran these commands (basically just replaying what the github action in the .yml does)
  5. cd weaver/core/network/fabric-interop-cc/contracts/interop
  6. go build -v ./...
  7. go test -v ./...
  8. The output of the test indicated that all the tests passed.
  9. Based on all the above, I think this is looking good.

[1] https://wiki.hyperledger.org/display/cactus/Daily+Pair+Programming+Calls [2] image

It's been a busy week, but I can use my weekend to try to improve. I would be very happy if you leave various instructions and little tips. Please share your knowledge with me.

Have a nice day.

@petermetz
Copy link
Contributor

@KaganCanSit One of the changes made in this PR was incorrect, causing the code to fail. The unit test for that module would have caught the error but was disabled.

Can you please work on a fix ASAP? I've added appropriate comments against the offending change.

@petermetz @sandeepnRES FYI.

@VRamakrishna Sorry, this is totally my fault! I still haven't re-enabled requiring the tests because the optimizations on the CI that would bring down the resource usage to acceptable levels are still pending. I'll work on tightening back up the CI because this is definitely a wake-up call in that sense.

@VRamakrishna
Copy link
Contributor

VRamakrishna commented Dec 18, 2023

@KaganCanSit Thanks for your explanation. Really appreciate your enterprise in finding potential vulnerabilities in the code base and trying to fix them. My comments were not meant as criticism of your effort and initiative but rather the completion of the task. The main problem was that the relevant test was disabled. If that wasn't the case, you'd have been alerted to the fact that more changes were needed in the code after your 128-->256 bit modification.

The right steps to test the module you touched are as follows:

  • cd weaver/common/protos-js
  • make build (Note: this builds data structures the SDK library depends on)
  • cd weaver/sdks/fabric/interoperation-node-sdk
  • make build-local
  • npm run test (Note: All tests should pass. Code coverage results can be ignored for now.)

The above steps are coded in the GitHub Action unit_test_weaver_node_sdk_local (see https://github.com/hyperledger/cacti/blob/main/.github/workflows/test_weaver-node-pkgs.yaml#L25).

I think the change to AES-256-CTR does need to be done (based on long-term security concerns), but you can take your time with it. For now, to avoid inconsistencies, I'm going to submit a PR reverting just that change (the rest of your changes in this PR looked good to me.)

@VRamakrishna
Copy link
Contributor

@KaganCanSit One of the changes made in this PR was incorrect, causing the code to fail. The unit test for that module would have caught the error but was disabled.
Can you please work on a fix ASAP? I've added appropriate comments against the offending change.
@petermetz @sandeepnRES FYI.

@VRamakrishna Sorry, this is totally my fault! I still haven't re-enabled requiring the tests because the optimizations on the CI that would bring down the resource usage to acceptable levels are still pending. I'll work on tightening back up the CI because this is definitely a wake-up call in that sense.

@petermetz Don't worry about it. I understood the rationale for disabling many of the tests earlier, but perhaps it's time to re-enable the mandatory unit tests now so problems like these don't slip through the cracks.

@VRamakrishna
Copy link
Contributor

@KaganCanSit @petermetz I opened a PR which should fix this issue by making the key length configurable: https://github.com/hyperledger/cacti/pull/2953.

@KaganCanSit
Copy link
Contributor Author

VRamakrishna

@VRamakrishna thank you for sharing your knowledge with me. I know you don't criticize me and you guide me. As an engineer candidate at the beginning of my journey, I think I will learn a lot from the open source world that will broaden my horizons. I respect your knowledge and effort. I will try to research and make a correction for my mistake here as soon as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

fix(weaver): usage of weak PRNG
4 participants