How to sign and verify string using ssh key using java - java

I know this issue may be duplicated somewhere else, but i wasted a lot of time to fix this issue.
I need to use third party API and as per their documentation i have to generate private/public key using the command ssh-keygen -t rsa, send to them the public key and for every request i must sign the request body using my private key
i found many code sample to read private/public key of formats like pem or der, but not the format generated using ssh-keygen -t rsa
my private key now is
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,07E3CD04C0D5E7AEC5BFB3660C389A79
iP+UVOT9UUma638HRLzyd9hLeZGbs2NxTakIWCB5Inpvd5+O4vcdjNhmV3zxSyDY
JpHlU8417Fyn3qHjHbG2Tj86qgFeexcZ83pjXxFU8JnXfqutSe6Zpa4sDuZYKve6
Xv2oxF64pVqEesH+C9XOkyYiWVqr09vpKBlIM2GcI2WqQwLuDYhj/AAWJhpKGVJu
+fwiQj7VS+tzBE1QW4Kva5xwEE4z/XZHkYMNDHUXBPeifsYXwkz8ZcXlcVZ+CAql
jwKh4ORXkBO/Ok2wva3dFfU7no2YSNIDhgHFGK6C9n5igbstYbTEPEH/YeSbqz1L
SucLiftfdvL9UdFb1/NQfcFhusNPHctGybvfAzttQEfSU/W5OYcN25SKF5pHUtHZ
Widu5M3JFCJ5Gw0P2sjANZVN/+8p0alT61dy6OqLckJmJfixpkvRQqdEP8ucUlTe
r+X5Fe2xH+cYh2MLq9IXxrK4g0sUZKoZw4AGKq24CfvD2K7UqHlXVO1hocyhlq+m
rRCVvRLJc7mpvpBtIQ6qXbr1chMa3zgkf6jW9thJ40jt4Giarj5s80fSC3Dk3lQN
ENV7nnhmd2uzz5yXx4sITnoDnItYDcJZk5pcOR4FAjUR2wRaLokae0pdEbS4heMa
KPOGOZGJNxs2CpwFUZL3CKIVMOmh14pzjZ4DNb9yzVhyd6wag5HlN9JNB1322eDO
lzfEnyki45wVGnB6ChthOnDRdgP5CUK+eaGqO8BSS+wttR25+MbZEwyljoQXc59h
XbGL5qqxpzrIT9+wDrEq8QNUaIg5OEXvBLa3NVOWSStgx+q5gqb5mzwJVdJiqSfL
xGG0CcyKuDPi6Vt/GKx5SGYi0gHFBs3QlYwzvvBxb5xKTc/meQSCM2ALXuJrFjBT
hXCBRBQ4F6i3pnyqkPJ36hsQ/mv6AWtsNhkMs2LrMjic0Fl5OhU6m1YA1nx8qz8k
ZQBhSWxLaTVwQsYnkH6SApPSo0t+FIzQfpnyYj4A9o6uK3dOiXPZndKqKx4mwqwM
uszlfMobhZUn2+ZcILXSZb1nNrwHKANRsp+I4j8bjG7qYKS5dfPaeIxRVQnpCkK+
SVznB0x8/EtIb8mLvuFtQap9KQ1S5UQxF3HhFoHdKjbDlEhMI3KPzURgYpis8K0y
M6jUbBnFQog9rSRCM79qE/cK6FX/QHrZt1Ijb9sPo54Y1TJQhbTempQ8N8SLnJFE
SY7W9wqOjyjrIKJ1NAWVSAHKu3ctUZHqWqijykkGa/t09BmtKoaHJ3RTJmQ7r/Z2
nxnARy9lDBSXgp8ErcYcf1eeRtCeRMZY+22F8gD7jJ/uKeEj6k8oUITt/dYSJWeA
LI9rPYydva8cNi0RtcB8Vgddi+GnhnGnhIXs3swk4AiVhBAPlAEfMdp3MjARrkJI
2UuMHStfht96aD3x3mL4fP0o6fJ5jSj/aCepwuR18xUHgtCCO8Sj81NBwPTSv654
XzIngNY3OPAOqo3RmS+xSnH8sCwE/wJxVu2sa/Ue8XszsjrzO4plYKh344MdR6g3
ISWyjPnFsdL1gBxoiPGfM/EF0bd4a1iGHDk4Ih4AcPgpgMwgN2VYDvGcxHEkQ0Y9
-----END RSA PRIVATE KEY-----
my public key
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDZ98gmTkAoteabP96SmMDWAsPYIj5tV4iovMC9IEeWtiV1DbOIYVYpp27YM2DezoEuBwbccG9+A2wygyYKAVJurfmQTTL4h2WxJ5UIRJtwKrc2UKZNA6amUfIEcQHt0qJeTk6t5Havte2eTU3P6p15J7sHonLdeVBqybjeUMTOc8g41uUtTtmgTSp3BORkY/qwYzC7bICWZuuoklathRgj0CATkfkz25kggV/cNiWo8Ngr2mM8qB3EZxidF6FYwGROYRFq9jPfn1K3EvgOWWsPeHwd/bJn109sTqaLY5TsKuatxZAE+3CHNoQsEGaAVtEz505Oa8IRJYp9LERuBHx1 melad#pcwrk005.bovc.dk
how to read these files using java and sign,verify strings using them

Related

Decoding - from Java to Powershell

I have inherited a self-made certification solution based on Java and Microsoft SQL server. We are moving forward to a Venafi solution. The old certificate has to be moved from the old solution to a Venafi pki solution. The designer of the old solution is not here anymore, but I have the decryption part in Java, including the decryption key. I have absolutely no experience in Java, and very limited cryptographic experience in Powershell.
The Java code to decrypt is this:
SecretKeySpec key = new SecretKeySpec(Base64.decode(encryptionkey.getBytes()), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] original = cipher.doFinal(encrypted);
The password is something like: gTsLrRTFR5Q0cvQZFRuZPw== (Not the actual password) and the certificates in encrypted format is basic hex data like 0x5F4E23E1 ... all in 1024 sizes.
How would I decrypt these certificates in powershell?
I'm not the specialist for powershell so I can just give you some hints to run the decryption part, for tasks like "get all files in folder with ending *.enc"
I'm leaving it to you to find a solution.
Assuming you are having a key in the format
MTIzNDU2Nzg5MDEyMzQ1Ng==
then it is a Base64-encode key. If all of your 30.000 certificates were encrypted with the same key then simply get the hex encoded value of the key
using an online service like https://base64.guru/converter/decode/hex.
Just enter the string above and press convert Base64 to Hex and you receive the key as follows:
31323334353637383930313233343536
Now count the chars - here we have 32 chars that mean it is a 16 byte (128 bit) long key used for AES cryptography. It's not a joke to count them because
the length of the key is important for the decryption task.
Having a certificate-file that was encrypted with a 32-char long hex-key ("cert32.enc") you use openssl (can be used in powershell as well as in many
other scripting languages) with this command (it is important to use the -K-option with a capital K and the hexstring enclosed with quotation marks):
openssl enc -aes-128-ecb -d -in cert32.enc -out cert.pem -K "31323334353637383930313233343536"
This will decode you the original certificate to the file "cert.pem" as follows (it is a sample certificate !):
-----BEGIN CERTIFICATE-----
MIIEETCCAvmgAwIBAgIUP2GufsPxg8R2n6L161b6wauxnGYwDQYJKoZIhvcNAQEL
BQAwgZcxCzAJBgNVBAYTAkRFMRIwEAYDVQQIDAlzb21lU3RhdGUxDTALBgNVBAcM
BGNpdHkxEDAOBgNVBAoMB2NvbXBhbnkxEDAOBgNVBAsMB3NlY3Rpb24xHzAdBgNV
BAMMFmphdmFjcnlwdG9AYnBsYWNlZC5uZXQxIDAeBgkqhkiG9w0BCQEWEWphdmFj
cnlwdG9AZ214LmRlMB4XDTIwMDcxMTA4MDMxNloXDTIxMDcxMTA4MDMxNlowgZcx
CzAJBgNVBAYTAkRFMRIwEAYDVQQIDAlzb21lU3RhdGUxDTALBgNVBAcMBGNpdHkx
EDAOBgNVBAoMB2NvbXBhbnkxEDAOBgNVBAsMB3NlY3Rpb24xHzAdBgNVBAMMFmph
dmFjcnlwdG9AYnBsYWNlZC5uZXQxIDAeBgkqhkiG9w0BCQEWEWphdmFjcnlwdG9A
Z214LmRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv1fayJg6TO7D
NASipOooJu9aYxLfw5/jokbaggOkL7wPQ2+eWk3tby72jMFniWySm6YIkiTbewYo
8WKl94zWTT8xx5pg/eOh28BTQLsi0/s9RF37z+eJA1TjA6TuBesNevm3V310H93Y
BLTA2Mjp/99W/smBhefaeYEkLh6TrZAAi2JtUHrs0FwNREoXrRIfq9monpUpY7lr
YRSy70nEaEyctw6khxeTRVRR97ZdqogLl2oEur9k5NKD8XHJ6A7MYz+asLMYNcnA
0jV02wR+b6etEr1tAtnswdxQ5T6tLrAnoen5v/fXSDnz93L7oRmTPsQJhK55TrrM
G+RWvV8aoQIDAQABo1MwUTAdBgNVHQ4EFgQULdU7CowdOtePac360y4n9aEbP2ow
HwYDVR0jBBgwFoAULdU7CowdOtePac360y4n9aEbP2owDwYDVR0TAQH/BAUwAwEB
/zANBgkqhkiG9w0BAQsFAAOCAQEAcP6EBsscMFAg0mMTLnd7+7VJzLuodPBAxiMS
zCYtUNS0KPBBR6OrGbHTbbvYd8/VGORpaWORfm0MDLP2kIxLKCYn4l7Wwoou7Idc
+Z+mohQKPwjtHnMZX6HyiCpmDF+qNR7dpOKpIsMahm9zVD8rfySFzr5oDSa7zFSr
MyJKmnz5I+gkUjJKvjYpKPjv7yuENhCbj4roNYK7ztN/vU6yJnFmzOaomP4MxhlE
GDoucjmy+qdGWF/i3Kh8n7zXBxRoBJZSkGqPE2N0PLIJlAFxb9c2QjPu5rmtZiDO
HiFj2Xk7jayMNw3JNVcayHjAcdHkp/u/BgTeqJWZRC+GsMz7ag==
-----END CERTIFICATE-----
Now we are working with the other key length (64 chars long). Having a base64 that looks like
MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=
you will get the hex-string with 64 characters:
3132333435363738393031323334353637383930313233343536373839303132
Now we are running the openssl-commandline with a similar algorithm (and another filename/key):
openssl enc -aes-256-ecb -d -in cert64.enc -out cert.pem -K "3132333435363738393031323334353637383930313233343536373839303132"
Voila, it's decoding to the same cert.pem as above.
All files are available via my GitHub repo for easy testing:
https://github.com/java-crypto/Stackoverflow/tree/master/Decoding_from_Java_to_Powershell

What is the difference between RSA private key with headers and OPENSSH private key? [duplicate]

This question already has answers here:
"Invalid privatekey" when using JSch
(9 answers)
Closed 3 years ago.
I'm setting up SFTP delivery of files to a server using public/private keys generated with ssh-keygen on mac. The private key I generated looks different from other private keys already in the codebase (it doesn't have headers and it's an "OPENSSH PRIVATE KEY" instead of "RSA PRIVATE KEY".
My java FtpUtil is throwing invalid privatekey error.
Is this because the key I generated is not correctly formatted in some way? Is there a way to change this private key to use headers?
This is what other private keys in the codebase look like:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,E26BE59A622AEDE6A899FE18AD369AA0
<key text>
-----END RSA PRIVATE KEY-----
This is what my private key looks like:
-----BEGIN OPENSSH PRIVATE KEY-----
<key text>
-----END OPENSSH PRIVATE KEY-----
I'm getting the following exception thrown:
Caused by: com.jcraft.jsch.JSchException: invalid privatekey: [B#5c0f79f0
at com.jcraft.jsch.KeyPair.load(KeyPair.java:664)
at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:46)
at com.jcraft.jsch.JSch.addIdentity(JSch.java:442)
at org.springframework.integration.sftp.session.DefaultSftpSessionFactory.initJschSession(DefaultSftpSessionFactory.java:410)
at org.springframework.integration.sftp.session.DefaultSftpSessionFactory.getSession(DefaultSftpSessionFactory.java:385)
... 46 more
It looks like this private key is not correctly formatted indeed.
Maybe it would be better to describe how did you generate private key and how is it processed within code?
Anyway if it's possible you can try to generate encrypted RSA private key using following:
openssl genrsa -des3 -out private_key.pem 2048

Detect PEM file content: certificate or public/private key?

I am trying to detect the content of a PEM file. In case it contains certificate infos, the following code is perfect to get X509Certificates informations:
X509Certificate cert = X509CertUtils.parse(Files.readAllBytes(file.toPath()));
but returns NULL of course if it's a key instead of certificate.
So is there a proper way to detect PEM content (mayb PEMReader and then instance of on the result. I tried with a ---- PRIVATE KEY ----- file but it returned null also)?
Of course, I can manually detect if file contain -----BEGIN CERTIFICATE----- or -----BEGIN PRIVATE KEY----- but I find this very careless.
Thank you !

Encrypt data using private key provided as text (i.e. without keystore)

There's a ton of documentation out there on how to create keystores and use them with java. Unfortunately that copious documentation entirely swamps anything out there on how to do encryption without using a keystore, and I've been unable to find a good starting point. I understand that most of the time keystores are a good idea. I have a very specific and oddball case (which I don't want to disclose the details of so don't ask) where I want to be able to provide a private key as text in a format similar to what is used for ssh in the .ssh/id_rsa private key file:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,508C51E6852AFF6BE89DB2B8A185DC4A
lG/N0foobarbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842foobarb
azfobarfoobarbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fooba
rbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fjdsjkfdsjklfadsj
azfobarfoobarbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fooba
rbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fjdsjkfdsjklfadsj
azfobarfoobarbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fooba
rbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fjdsjkfdsjklfadsj
azfobarfoobarbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fooba
rbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fjdsjkfdsjklfadsj
azfobarfoobarbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fooba
rbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fjdsjkfdsjklfadsj
azfobarfoobarbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fooba
rbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fjdsjkfdsjklfadsj
azfobarfoobarbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fooba
rbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fjdsjkfdsjklfadsj
azfobarfoobarbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fooba
rbazfobarbazFoOB4R842foobarbazfobarbazFoOB4R842fjdsjkfdsj0b+FMFD
-----END RSA PRIVATE KEY-----
And then use that to encrypt some other data. One problem I have is that although I've set up numerous ssh accounts in the past I don't know the actual name of that particular format (is it PEM? but examples of pem I have seen while searching lack the Proc-Type and DEK-Info lines) so searching for javadoc or other advice on consuming it is not possible.
Questions are these: What is the name of the above format? What is the best way to consume that format from a Java String with the intent of using it to encrypt data (to later be decrypted with the matching public key of course)?

Help verifying RSA signed text with Python

Using Java I have created RSA keypairs. Using Java I can use these keys to sign and verify some text. I can also "export" these keys in PEM format and load them into a Python test script. Once in the Python script, I can use these keys to sign and verify some text using M2Crypto.
I have not yet been able to verify in Python the signature I created in Java.
Right now I am just trying to get cross-platform signing and verifying to work.
Here is Java snippet:
Signature sig = Signature.getInstance("MD5WithRSA");
sig.initSign(key.getPrivate());
sig.update("This is a message.".getBytes("UTF8"));
byte[] signatureBytes = sig.sign();
return Base64.encodeBytes(signatureBytes, Base64.DO_BREAK_LINES);
Which generates:
PIp4eLhA941xmpdqu7j60731R9oWSNWcHvwoVADKxABGoUE02eDS0qZ4yQD2vYBdRDXXxHV4UjtW
YQwv9nsOzCBWeDQ0vv6W0dLVfTBuk79On7AALuwnTFr8s0y5ZN5RINvPPR60mwONav26ZbPj4ub3
NZqUS/zkqyO8Z8D2zUjk0pqAhWDGbFBaWPQJBPOY9iRt8GlsAUkGfYGeIx9DNU8aiJmQ3NnUHbs4
5NEr3xydbNJjwK96kkNJ9vyKZRfnNd4eW2UllPiwJSRQgefCQfh79ZuiYeQEuk3HMh7Si4iYl7uU
rWCgYFl4fGV1X/k+BSHR4ZZFWGQ3IPfafYHyNw==
And here is the public key:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg+N7xQHVHU3VHMZ9VGFdUf6ud3rAL8YS
sfWv2zFMnKAjh6XacwDGX6jJR/0/pyDriRGw/uodBDSFvgn9XEM/srMYtbJ1KQ9R9ChDifixF3Hx
yzbzPRvFoEfZnS/63+d1r0wnafz7xx0eDEYE3TgRKTMikwOsuIOFWa7GhA4BvP7ad79bI5ORJdLu
9Je+k+4dbt0xk2t7YopxYmyU+4zhZMxuthJTr69rXgqhgsCRdK6kFIGm3YuJ1WQcci8OVwH+3o7F
XzJHpSTxH57m6PX5lXaywIDCbUauTpBV3w+0vTeGI/2o+U40qhLBkpZT9GSVKxgXl5a0XxrkwTGn
61XZqQIDAQAB
-----END PUBLIC KEY-----
Then in Python the key is loaded and the signature is attempted to be verified:
from M2Crypto import RSA, EVP
pub_key = RSA.load_pub_key('public_key.pem')
verify_evp = EVP.PKey()
verify_evp.assign_rsa(pub_key)
verify_evp.verify_init()
verify_evp.verify_update("This is a message.")
if verify_evp.verify_final(sig_string.decode('base64')) == 1:
print "Good"
else:
print "Bad"
And this does not verify. I suspect it is some leading or trailing characters or encoding weirdness that I don't understand.
I have no particular attachement to M2Crypto and have played a bit with the gdata.tlslite modules as well.
Please note that the keys are working, and that the text and signature above verify in Java, and the keys (public and private) can be used within Python to sign and verify text. The problem is somewhere in how Java-generated signature and/or the message text is getting into the Python code.
What am I doing wrong?
M2Crypto.EVP defaults to 'sha1' (SHA1) and you're using MD5WithRSA. I think you should switch SHA1WithRSA (MD5 is a very weak algorithm).

Categories

Resources