warehouse
warehouse copied to clipboard
2FA,Very inconvenient for users in Chinese Mainland
When logging into pypi, I received an email reminding me to enable 2FA verification for my account. However, none of the supported applications listed on the help page can be used by users in Chinese Mainland. To download Android applications, you need to use Google Play. This does not work. Please consider this situation. Thank you.
Hi @jkjoker, sorry you're having issues and thanks for reaching out.
Do you use a password manager? You might be able to use 1Password as an authenticator for sites with two-factor authentication or Authy for your personal computer depending on what platform you use.
You can also generate TOTP codes fairly trivially in Python with the cryptography package by using the string shown below the QR code during setup (under "No QR scanner? Manually enter the code instead")
import time
from cryptography.hazmat.primitives.hashes import SHA1
from cryptography.hazmat.primitives.twofactor.totp import TOTP
key = "YOUR SETUP STRING HERE"
decoded_key = base64.b32decode(key)
totp = TOTP(key, 6, SHA1(), 30)
print(totp.generate(time.time())
...where this will print the six-digit code you will need to provide to PyPI.
I think we can probably add these suggestions to our documentation for future reference.
Hi @jkjoker, sorry you're having issues and thanks for reaching out.
Do you use a password manager? You might be able to use 1Password as an authenticator for sites with two-factor authentication or Authy for your personal computer depending on what platform you use.
You can also generate TOTP codes fairly trivially in Python with the cryptography package by using the string shown below the QR code during setup (under "No QR scanner? Manually enter the code instead")
import time from cryptography.hazmat.primitives.hashes import SHA1 from cryptography.hazmat.primitives.twofactor.totp import TOTP key = "YOUR SETUP STRING HERE" decoded_key = base64.b32decode(key.encode()) totp = TOTP(key, 6, SHA1(), 30) print(totp.generate(time.time())
...where this will print the six-digit code you will need to provide to PyPI.
I think we can probably add these suggestions to our documentation for future reference.
Thank you for your help. After testing, the current situation is:
-
Authy can install, but cannot open and use it properly
-
1 password seems to be usable, but this is a paid application and I haven't delved deeper into it yet
-
As for the code mentioned above, I have used it, but it has not been successful. I have installed Cryptography normally and used the following code:
import time
import base64
from cryptography.hazmat.primitives.hashes import SHA1
from cryptography.hazmat.primitives.twofactor.totp import TOTP
key = "QX7EL3XR3YG5EOVDZTN3TXVNOOWHWIEY" # Enter your own verification code, this string of codes has expired and is only used as an example
decoded_key = base64.b32decode(key.encode())
totp = TOTP(key, 6, SHA1(), 30)
print(totp.generate(time.time()))
result:
TypeError: argument 'key': from_buffer() cannot return the address of a unicode object
My configuration is: windows10,python3.11.5
4.My current approach is: I have added 2FA to my account through pyotp and currently do not plan to log in to the webpage. If necessary, I will use a recovery code.
My thoughts on 2FA for reference:
- Leaving aside the issue of payment or not, even if using 1password, it is necessary to manage a 1password account, so there is no absolute security.
- Many websites receive verification codes through email and then log in. For example, Microsoft is like this. I think this method is more reasonable.
- Perhaps this method can also be considered: use recovery code every time you log in, and after logging in, more recovery codes can be generated in the background, even if two are generated, it would be good. Considering that we actually log in to the webpage very few times, this is also a reasonable approach.
In fact, no matter which method is used, there is no absolute safety, but personally, I still appreciate all the considerations and efforts you have made for safety. Thank you.
As for the code mentioned above, I have used it, but it has not been successful. I have installed Cryptography normally and used the following code:
Sorry, the line:
decoded_key = base64.b32decode(key.encode())
should be
decoded_key = base64.b32decode(key)
I've updated my example as well.
Perhaps this method can also be considered: use recovery code every time you log in, and after logging in, more recovery codes can be generated in the background, even if two are generated, it would be good. Considering that we actually log in to the webpage very few times, this is also a reasonable approach.
Yes, I think using recovery codes here as a workaround is a good option as well. I don't think we will ever automatically generate recovery codes for a user, but we can improve the flow when they have used all their codes to force them to regenerate them.
Leaving this open so we can include these options in our help page.
Hi,
Thanks for the help to set a 2FA, I have a similar issue as I do not have a smartphone. I tested the suggested code but I encountered the same issue (TypeError: argument 'key': from_buffer() cannot return the address of a unicode object
). I think it comes from this line:
totp = TOTP(key, 6, SHA1(), 30)
I was able to generate the code by replacing it with:
totp = TOTP(decoded_key, 6, SHA1(), 30)
I put this fix in this issue to check if it is correct and if it can help other people.
- Many websites receive verification codes through email and then log in. For example, Microsoft is like this. I think this method is more reasonable.
Microsoft also allows fully removing the password, by the way. One day, PyPI could allow this too: #13764.
By the way, another 2FA method is hardware FIDO 2 keys — these interface with your computing device via USB/NFC/Bluetooth and provide more a convenient solution. Moreover, modern phones have FIDO 2 built-in (no extra software required). So you can enroll your phone as a FIDO 2 device which would let you log in on your mobile with a fingerprint or a face id. Additionally, some OSs also have it built-in (no extra software required as well). The features you're looking for are called Windows Hello (for Windows) or Face/Touch ID (for macOS). There's no well-known alternative for GNU/Linux, though.
Well... there's one working way on the browser level through extensions — most of the modern password managers. I use Bitwarden, for example. While it doesn't have TOTP in the free subscription, it has free passkeys for everyone. And even though, PyPI doesn't support passkey, they do work as the second factor in 2FA (meaning you still have to type in your password) — I checked!
import time
import base64
from cryptography.hazmat.primitives.hashes import SHA1
from cryptography.hazmat.primitives.twofactor.totp import TOTP
key = ""
decoded_key = base64.b32decode(key)
totp = TOTP(decoded_key, 6, SHA1(), 30)
print(totp.generate(time.time()))