OpenSSL - How to create a RSA public key from module and exponent values

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

OpenSSL - How to create a RSA public key from module and exponent values

Jan van de Sandt
Hello list,

For a JSON API that we are implementing in VA Smalltalk we need to support JSON Web Tokens (JWT's). In order to validate the caller of our API we need to validate a RS256 (RSA PKCS#1 signature with SHA-256) signed JWT token.

We want to use the OpenSSL support that is shipped with VA Smalltalk to implement this. One step that we need to do is to setup a RSA public key that we retrieved as a JSON document.

An example:

The JSON document:

{
  "keys": [
    {
"kid":"X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk",
"nbf":1493763266,"use":"sig",
"kty":"RSA",
"e":"AQAB",
"n":"tVKUtcx_n9rt5afY_2WFNvU6PlFMggCatsZ3l4RjKxH0jgdLq6CScb0P3ZGXYbPzXvmmLiWZizpb-h0qup5jznOvOr-Dhw9908584BSgC83YacjWNqEK3urxhyE2jWjwRm2N95WGgb5mzE5XmZIvkvyXnn7X8dvgFPF5QwIngGsDG8LyHuJWlaDhr_EPLMW4wHvH0zZCuRMARIJmmqiMy3VD4ftq4nS5s8vJL0pVSrkuNojtokp84AtkADCDU_BUhrc2sIgfnvZ03koCQRoZmWiHu86SuJZYkDFstVTVSR0hiXudFlfQ2rOhPlpObmku68lXw-7V-P7jwrQRFfQVXw"
}
  ]
}

The "e" field contains the exponent of the RSA public key and the "n" field contains the modulo field.

First thing is to url/base64 decode the fields. Than we have two byte arrays:

| bytesE bytesN publicKey |
byestE := #[1 0 1].
bytesN := #[181 82 148 181 204 127 159 218 237 229 167 216 255 101 133 54 245 58 62 81 76 130 0 154 182 198 119 151 132 99 43 17 244 142 7 75 171 160 146 113 189 15 221 145 151 97 179 243 94 249 166 46 37 153 139 58 91 250 29 42 186 158 99 206 115 175 58 191 131 135 15 125 211 206 124 224 20 160 11 205 216 105 200 214 54 161 10 222 234 241 135 33 54 141 104 240 70 109 141 247 149 134 129 190 102 204 78 87 153 146 47 146 252 151 158 126 215 241 219 224 20 241 121 67 2 39 128 107 3 27 194 242 30 226 86 149 160 225 175 241 15 44 197 184 192 123 199 211 54 66 185 19 0 68 130 102 154 168 140 203 117 67 225 251 106 226 116 185 179 203 201 47 74 85 74 185 46 54 136 237 162 74 124 224 11 100 0 48 131 83 240 84 134 183 54 176 136 31 158 246 116 222 74 2 65 26 25 153 104 135 187 206 146 184 150 88 144 49 108 181 84 213 73 29 33 137 123 157 22 87 208 218 179 161 62 90 78 110 105 46 235 201 87 195 238 213 248 254 227 194 180 17 21 244 21 95].

"How to create a RSA public key??? -- this does not work"
publicKey := OSSslRSAKey createNewFromBytes: bytesN.

We can't figure out how to create the public key from the byte arrays. Any help would be really appriciated!

Kind regards,
Jan.





--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/va-smalltalk.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: OpenSSL - How to create a RSA public key from module and exponent values

Seth Berman
Greetings Jan,

createNewFromBytes: is for DER or PEM encoded in-memory data.

This won't solve your actual problem, but when providing parameters you want to use the #createNew: method.
The #createNew: method doc says
"The argument @bitsOrBitsAndExponent can be:
1. An <Association> with the key <Integer> length in BITS and 
    a value <Integer> the public exponent.  If the exponent is nil, 
then the constant value OpenSSLCryptoConstants::RSA_F4 (6537) will be used.
2. An <Integer> to just define the bits...this is shorthand for a nil exponent described
    above."

This means you generate RSA keys with either
publicKey := OSSslRSAKey createNew: 256.
or
publicKey := OSSslRSAKey createNew: 256 -> bytesE asOpenSSLBigNumber.  "<-- Convert public exponent byte array in big-endian format to number"

But you can see that this is a key generator method and uses OpenSSL's RSA_generate_key_ex function.
What your after is setting both e and n manually instead of generating n.
Typically, you would read these public values from bytes or a file using the #createNewFromFile: or #createNewFromBytes: methods where the the input is DER or PEM encoded.
If you can get the public parameters in these terms then you could use one of those methods (probably createNewFromBytes: since your doing this in memory).

There is another option but the behavior has not been officially exposed in VA.  You would need to grab the low-level RSA struct and manually set e and n.
Given that the RSA struct has gone opaque since 1.1.0, this needs to be done carefully if you need to support multiple versions.

If you want to send in a support ticket to [hidden email], I can work with you more on this.

-- Seth

On Monday, February 5, 2018 at 5:48:22 AM UTC-5, Jan van de Sandt wrote:
Hello list,

For a JSON API that we are implementing in VA Smalltalk we need to support JSON Web Tokens (JWT's). In order to validate the caller of our API we need to validate a RS256 (RSA PKCS#1 signature with SHA-256) signed JWT token.

We want to use the OpenSSL support that is shipped with VA Smalltalk to implement this. One step that we need to do is to setup a RSA public key that we retrieved as a JSON document.

An example:

The JSON document:

{
  "keys": [
    {
"kid":"X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk",
"nbf":1493763266,"use":"sig",
"kty":"RSA",
"e":"AQAB",
"n":"tVKUtcx_n9rt5afY_2WFNvU6PlFMggCatsZ3l4RjKxH0jgdLq6CScb0P3ZGXYbPzXvmmLiWZizpb-h0qup5jznOvOr-Dhw9908584BSgC83YacjWNqEK3urxhyE2jWjwRm2N95WGgb5mzE5XmZIvkvyXnn7X8dvgFPF5QwIngGsDG8LyHuJWlaDhr_EPLMW4wHvH0zZCuRMARIJmmqiMy3VD4ftq4nS5s8vJL0pVSrkuNojtokp84AtkADCDU_BUhrc2sIgfnvZ03koCQRoZmWiHu86SuJZYkDFstVTVSR0hiXudFlfQ2rOhPlpObmku68lXw-7V-P7jwrQRFfQVXw"
}
  ]
}

The "e" field contains the exponent of the RSA public key and the "n" field contains the modulo field.

First thing is to url/base64 decode the fields. Than we have two byte arrays:

| bytesE bytesN publicKey |
byestE := #[1 0 1].
bytesN := #[181 82 148 181 204 127 159 218 237 229 167 216 255 101 133 54 245 58 62 81 76 130 0 154 182 198 119 151 132 99 43 17 244 142 7 75 171 160 146 113 189 15 221 145 151 97 179 243 94 249 166 46 37 153 139 58 91 250 29 42 186 158 99 206 115 175 58 191 131 135 15 125 211 206 124 224 20 160 11 205 216 105 200 214 54 161 10 222 234 241 135 33 54 141 104 240 70 109 141 247 149 134 129 190 102 204 78 87 153 146 47 146 252 151 158 126 215 241 219 224 20 241 121 67 2 39 128 107 3 27 194 242 30 226 86 149 160 225 175 241 15 44 197 184 192 123 199 211 54 66 185 19 0 68 130 102 154 168 140 203 117 67 225 251 106 226 116 185 179 203 201 47 74 85 74 185 46 54 136 237 162 74 124 224 11 100 0 48 131 83 240 84 134 183 54 176 136 31 158 246 116 222 74 2 65 26 25 153 104 135 187 206 146 184 150 88 144 49 108 181 84 213 73 29 33 137 123 157 22 87 208 218 179 161 62 90 78 110 105 46 235 201 87 195 238 213 248 254 227 194 180 17 21 244 21 95].

"How to create a RSA public key??? -- this does not work"
publicKey := OSSslRSAKey createNewFromBytes: bytesN.

We can't figure out how to create the public key from the byte arrays. Any help would be really appriciated!

Kind regards,
Jan.





--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/va-smalltalk.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: OpenSSL - How to create a RSA public key from module and exponent values

Jan van de Sandt
Hello Seth,

Thank you for this info. I found some OpenSSL C samples on stackoverflow where they set the "e" and "n" BIGNUM fields of an RSA key. I think this is the same approach you are suggesting. But I haven't figured out how to do this from VA Smalltalk yet.

I will ask my team members if submitting  a support ticket is the way to gore here.

Jan.


On Mon, Feb 5, 2018 at 3:43 PM, Seth Berman <[hidden email]> wrote:
Greetings Jan,

createNewFromBytes: is for DER or PEM encoded in-memory data.

This won't solve your actual problem, but when providing parameters you want to use the #createNew: method.
The #createNew: method doc says
"The argument @bitsOrBitsAndExponent can be:
1. An <Association> with the key <Integer> length in BITS and 
    a value <Integer> the public exponent.  If the exponent is nil, 
then the constant value OpenSSLCryptoConstants::RSA_F4 (6537) will be used.
2. An <Integer> to just define the bits...this is shorthand for a nil exponent described
    above."

This means you generate RSA keys with either
publicKey := OSSslRSAKey createNew: 256.
or
publicKey := OSSslRSAKey createNew: 256 -> bytesE asOpenSSLBigNumber.  "<-- Convert public exponent byte array in big-endian format to number"

But you can see that this is a key generator method and uses OpenSSL's RSA_generate_key_ex function.
What your after is setting both e and n manually instead of generating n.
Typically, you would read these public values from bytes or a file using the #createNewFromFile: or #createNewFromBytes: methods where the the input is DER or PEM encoded.
If you can get the public parameters in these terms then you could use one of those methods (probably createNewFromBytes: since your doing this in memory).

There is another option but the behavior has not been officially exposed in VA.  You would need to grab the low-level RSA struct and manually set e and n.
Given that the RSA struct has gone opaque since 1.1.0, this needs to be done carefully if you need to support multiple versions.

If you want to send in a support ticket to [hidden email], I can work with you more on this.

-- Seth

On Monday, February 5, 2018 at 5:48:22 AM UTC-5, Jan van de Sandt wrote:
Hello list,

For a JSON API that we are implementing in VA Smalltalk we need to support JSON Web Tokens (JWT's). In order to validate the caller of our API we need to validate a RS256 (RSA PKCS#1 signature with SHA-256) signed JWT token.

We want to use the OpenSSL support that is shipped with VA Smalltalk to implement this. One step that we need to do is to setup a RSA public key that we retrieved as a JSON document.

An example:

The JSON document:

{
  "keys": [
    {
"kid":"X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk",
"nbf":1493763266,"use":"sig",
"kty":"RSA",
"e":"AQAB",
"n":"tVKUtcx_n9rt5afY_2WFNvU6PlFMggCatsZ3l4RjKxH0jgdLq6CScb0P3ZGXYbPzXvmmLiWZizpb-h0qup5jznOvOr-Dhw9908584BSgC83YacjWNqEK3urxhyE2jWjwRm2N95WGgb5mzE5XmZIvkvyXnn7X8dvgFPF5QwIngGsDG8LyHuJWlaDhr_EPLMW4wHvH0zZCuRMARIJmmqiMy3VD4ftq4nS5s8vJL0pVSrkuNojtokp84AtkADCDU_BUhrc2sIgfnvZ03koCQRoZmWiHu86SuJZYkDFstVTVSR0hiXudFlfQ2rOhPlpObmku68lXw-7V-P7jwrQRFfQVXw"
}
  ]
}

The "e" field contains the exponent of the RSA public key and the "n" field contains the modulo field.

First thing is to url/base64 decode the fields. Than we have two byte arrays:

| bytesE bytesN publicKey |
byestE := #[1 0 1].
bytesN := #[181 82 148 181 204 127 159 218 237 229 167 216 255 101 133 54 245 58 62 81 76 130 0 154 182 198 119 151 132 99 43 17 244 142 7 75 171 160 146 113 189 15 221 145 151 97 179 243 94 249 166 46 37 153 139 58 91 250 29 42 186 158 99 206 115 175 58 191 131 135 15 125 211 206 124 224 20 160 11 205 216 105 200 214 54 161 10 222 234 241 135 33 54 141 104 240 70 109 141 247 149 134 129 190 102 204 78 87 153 146 47 146 252 151 158 126 215 241 219 224 20 241 121 67 2 39 128 107 3 27 194 242 30 226 86 149 160 225 175 241 15 44 197 184 192 123 199 211 54 66 185 19 0 68 130 102 154 168 140 203 117 67 225 251 106 226 116 185 179 203 201 47 74 85 74 185 46 54 136 237 162 74 124 224 11 100 0 48 131 83 240 84 134 183 54 176 136 31 158 246 116 222 74 2 65 26 25 153 104 135 187 206 146 184 150 88 144 49 108 181 84 213 73 29 33 137 123 157 22 87 208 218 179 161 62 90 78 110 105 46 235 201 87 195 238 213 248 254 227 194 180 17 21 244 21 95].

"How to create a RSA public key??? -- this does not work"
publicKey := OSSslRSAKey createNewFromBytes: bytesN.

We can't figure out how to create the public key from the byte arrays. Any help would be really appriciated!

Kind regards,
Jan.





--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/va-smalltalk.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/va-smalltalk.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: OpenSSL - How to create a RSA public key from module and exponent values

Seth Berman
Hi Jan,

I think this is what you are looking for...but not completely sure.  This would probably still work on OpenSSL 1.1.0, but it's not ideal because it is making assumptions about the location of e and n within the struct.

| bytesE bytesN publicKey rsaStruct e n message encrypted |
bytesE := #[1 0 1].
bytesN := #[181 82 148 181 204 127 159 218 237 229 167 216 255 101 133 54 245 58 62 81 76 130 0 154 182 198 119 151 132 99 43 17 244 142 7 75 171 160 146 113 189 15 221 145 151 97 179 243 94 249 166 46 37 153 139 58 91 250 29 42 186 158 99 206 115 175 58 191 131 135 15 125 211 206 124 224 20 160 11 205 216 105 200 214 54 161 10 222 234 241 135 33 54 141 104 240 70 109 141 247 149 134 129 190 102 204 78 87 153 146 47 146 252 151 158 126 215 241 219 224 20 241 121 67 2 39 128 107 3 27 194 242 30 226 86 149 160 225 175 241 15 44 197 184 192 123 199 211 54 66 185 19 0 68 130 102 154 168 140 203 117 67 225 251 106 226 116 185 179 203 201 47 74 85 74 185 46 54 136 237 162 74 124 224 11 100 0 48 131 83 240 84 134 183 54 176 136 31 158 246 116 222 74 2 65 26 25 153 104 135 187 206 146 184 150 88 144 49 108 181 84 213 73 29 33 137 123 157 22 87 208 218 179 161 62 90 78 110 105 46 235 201 87 195 238 213 248 254 227 194 180 17 21 244 21 95].

e := bytesE asOpenSSLBigNumber.
n := bytesN asOpenSSLBigNumber.
publicKey := OSSslRSAKey createNew.
rsaStruct := publicKey algorithmPkeyObject.
rsaStruct 
pointerAt: #e put: (e dispatcher callBN_dupWith: e);   "<-- non-managed duplicate since it's lifecycle is dictated by rsaStruct"
pointerAt: #n put: (n dispatcher callBN_dupWith: n).   ""<-- non-managed duplicate since it's lifecycle is dictated by rsaStruct"

message := 'Hello Smalltalk'.
encrypted := publicKey publicKeyEncrypt: message pad: nil.
"There is also publicKeyDecrypt:pad: if needed"

-- Seth

On Monday, February 5, 2018 at 10:29:47 AM UTC-5, Jan van de Sandt wrote:
Hello Seth,

Thank you for this info. I found some OpenSSL C samples on stackoverflow where they set the "e" and "n" BIGNUM fields of an RSA key. I think this is the same approach you are suggesting. But I haven't figured out how to do this from VA Smalltalk yet.

I will ask my team members if submitting  a support ticket is the way to gore here.

Jan.

[1] <a href="https://stackoverflow.com/questions/48284053/set-rsa-key-and-extract-private-key-from-openssl" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fstackoverflow.com%2Fquestions%2F48284053%2Fset-rsa-key-and-extract-private-key-from-openssl\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFJuwFAX9GWH5bKJoVYalC1KTw_fw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fstackoverflow.com%2Fquestions%2F48284053%2Fset-rsa-key-and-extract-private-key-from-openssl\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFJuwFAX9GWH5bKJoVYalC1KTw_fw&#39;;return true;">https://stackoverflow.com/questions/48284053/set-rsa-key-and-extract-private-key-from-openssl

On Mon, Feb 5, 2018 at 3:43 PM, Seth Berman <[hidden email]> wrote:
Greetings Jan,

createNewFromBytes: is for DER or PEM encoded in-memory data.

This won't solve your actual problem, but when providing parameters you want to use the #createNew: method.
The #createNew: method doc says
"The argument @bitsOrBitsAndExponent can be:
1. An <Association> with the key <Integer> length in BITS and 
    a value <Integer> the public exponent.  If the exponent is nil, 
then the constant value OpenSSLCryptoConstants::RSA_F4 (6537) will be used.
2. An <Integer> to just define the bits...this is shorthand for a nil exponent described
    above."

This means you generate RSA keys with either
publicKey := OSSslRSAKey createNew: 256.
or
publicKey := OSSslRSAKey createNew: 256 -> bytesE asOpenSSLBigNumber.  "<-- Convert public exponent byte array in big-endian format to number"

But you can see that this is a key generator method and uses OpenSSL's RSA_generate_key_ex function.
What your after is setting both e and n manually instead of generating n.
Typically, you would read these public values from bytes or a file using the #createNewFromFile: or #createNewFromBytes: methods where the the input is DER or PEM encoded.
If you can get the public parameters in these terms then you could use one of those methods (probably createNewFromBytes: since your doing this in memory).

There is another option but the behavior has not been officially exposed in VA.  You would need to grab the low-level RSA struct and manually set e and n.
Given that the RSA struct has gone opaque since 1.1.0, this needs to be done carefully if you need to support multiple versions.

If you want to send in a support ticket to [hidden email], I can work with you more on this.

-- Seth

On Monday, February 5, 2018 at 5:48:22 AM UTC-5, Jan van de Sandt wrote:
Hello list,

For a JSON API that we are implementing in VA Smalltalk we need to support JSON Web Tokens (JWT's). In order to validate the caller of our API we need to validate a RS256 (RSA PKCS#1 signature with SHA-256) signed JWT token.

We want to use the OpenSSL support that is shipped with VA Smalltalk to implement this. One step that we need to do is to setup a RSA public key that we retrieved as a JSON document.

An example:

The JSON document:

{
  "keys": [
    {
"kid":"X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk",
"nbf":1493763266,"use":"sig",
"kty":"RSA",
"e":"AQAB",
"n":"tVKUtcx_n9rt5afY_2WFNvU6PlFMggCatsZ3l4RjKxH0jgdLq6CScb0P3ZGXYbPzXvmmLiWZizpb-h0qup5jznOvOr-Dhw9908584BSgC83YacjWNqEK3urxhyE2jWjwRm2N95WGgb5mzE5XmZIvkvyXnn7X8dvgFPF5QwIngGsDG8LyHuJWlaDhr_EPLMW4wHvH0zZCuRMARIJmmqiMy3VD4ftq4nS5s8vJL0pVSrkuNojtokp84AtkADCDU_BUhrc2sIgfnvZ03koCQRoZmWiHu86SuJZYkDFstVTVSR0hiXudFlfQ2rOhPlpObmku68lXw-7V-P7jwrQRFfQVXw"
}
  ]
}

The "e" field contains the exponent of the RSA public key and the "n" field contains the modulo field.

First thing is to url/base64 decode the fields. Than we have two byte arrays:

| bytesE bytesN publicKey |
byestE := #[1 0 1].
bytesN := #[181 82 148 181 204 127 159 218 237 229 167 216 255 101 133 54 245 58 62 81 76 130 0 154 182 198 119 151 132 99 43 17 244 142 7 75 171 160 146 113 189 15 221 145 151 97 179 243 94 249 166 46 37 153 139 58 91 250 29 42 186 158 99 206 115 175 58 191 131 135 15 125 211 206 124 224 20 160 11 205 216 105 200 214 54 161 10 222 234 241 135 33 54 141 104 240 70 109 141 247 149 134 129 190 102 204 78 87 153 146 47 146 252 151 158 126 215 241 219 224 20 241 121 67 2 39 128 107 3 27 194 242 30 226 86 149 160 225 175 241 15 44 197 184 192 123 199 211 54 66 185 19 0 68 130 102 154 168 140 203 117 67 225 251 106 226 116 185 179 203 201 47 74 85 74 185 46 54 136 237 162 74 124 224 11 100 0 48 131 83 240 84 134 183 54 176 136 31 158 246 116 222 74 2 65 26 25 153 104 135 187 206 146 184 150 88 144 49 108 181 84 213 73 29 33 137 123 157 22 87 208 218 179 161 62 90 78 110 105 46 235 201 87 195 238 213 248 254 227 194 180 17 21 244 21 95].

"How to create a RSA public key??? -- this does not work"
publicKey := OSSslRSAKey createNewFromBytes: bytesN.

We can't figure out how to create the public key from the byte arrays. Any help would be really appriciated!

Kind regards,
Jan.





--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/va-smalltalk" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/va-smalltalk&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/va-smalltalk&#39;;return true;">https://groups.google.com/group/va-smalltalk.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/va-smalltalk.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: OpenSSL - How to create a RSA public key from module and exponent values

Jan van de Sandt
Hi Seth,

Yes, this is exactly what I was looking for. Your example works with OpenSSL 1.0.0. For OpenSSL version 1.1.0 it worked after I executed OSSslRSA class >> #initializeVersionLayout10.

If OpenSSL makes a structure opaque it would be nice if they provided some public function to set a public key using the exponent and modules integers.

Thanks for the help! Now I can continue with the JWT token validation logic.

Regards,
Jan.




On Mon, Feb 5, 2018 at 5:27 PM, Seth Berman <[hidden email]> wrote:
Hi Jan,

I think this is what you are looking for...but not completely sure.  This would probably still work on OpenSSL 1.1.0, but it's not ideal because it is making assumptions about the location of e and n within the struct.

| bytesE bytesN publicKey rsaStruct e n message encrypted |
bytesE := #[1 0 1].
bytesN := #[181 82 148 181 204 127 159 218 237 229 167 216 255 101 133 54 245 58 62 81 76 130 0 154 182 198 119 151 132 99 43 17 244 142 7 75 171 160 146 113 189 15 221 145 151 97 179 243 94 249 166 46 37 153 139 58 91 250 29 42 186 158 99 206 115 175 58 191 131 135 15 125 211 206 124 224 20 160 11 205 216 105 200 214 54 161 10 222 234 241 135 33 54 141 104 240 70 109 141 247 149 134 129 190 102 204 78 87 153 146 47 146 252 151 158 126 215 241 219 224 20 241 121 67 2 39 128 107 3 27 194 242 30 226 86 149 160 225 175 241 15 44 197 184 192 123 199 211 54 66 185 19 0 68 130 102 154 168 140 203 117 67 225 251 106 226 116 185 179 203 201 47 74 85 74 185 46 54 136 237 162 74 124 224 11 100 0 48 131 83 240 84 134 183 54 176 136 31 158 246 116 222 74 2 65 26 25 153 104 135 187 206 146 184 150 88 144 49 108 181 84 213 73 29 33 137 123 157 22 87 208 218 179 161 62 90 78 110 105 46 235 201 87 195 238 213 248 254 227 194 180 17 21 244 21 95].

e := bytesE asOpenSSLBigNumber.
n := bytesN asOpenSSLBigNumber.
publicKey := OSSslRSAKey createNew.
rsaStruct := publicKey algorithmPkeyObject.
rsaStruct 
pointerAt: #e put: (e dispatcher callBN_dupWith: e);   "<-- non-managed duplicate since it's lifecycle is dictated by rsaStruct"
pointerAt: #n put: (n dispatcher callBN_dupWith: n).   ""<-- non-managed duplicate since it's lifecycle is dictated by rsaStruct"

message := 'Hello Smalltalk'.
encrypted := publicKey publicKeyEncrypt: message pad: nil.
"There is also publicKeyDecrypt:pad: if needed"

-- Seth

On Monday, February 5, 2018 at 10:29:47 AM UTC-5, Jan van de Sandt wrote:
Hello Seth,

Thank you for this info. I found some OpenSSL C samples on stackoverflow where they set the "e" and "n" BIGNUM fields of an RSA key. I think this is the same approach you are suggesting. But I haven't figured out how to do this from VA Smalltalk yet.

I will ask my team members if submitting  a support ticket is the way to gore here.

Jan.


On Mon, Feb 5, 2018 at 3:43 PM, Seth Berman <[hidden email]> wrote:
Greetings Jan,

createNewFromBytes: is for DER or PEM encoded in-memory data.

This won't solve your actual problem, but when providing parameters you want to use the #createNew: method.
The #createNew: method doc says
"The argument @bitsOrBitsAndExponent can be:
1. An <Association> with the key <Integer> length in BITS and 
    a value <Integer> the public exponent.  If the exponent is nil, 
then the constant value OpenSSLCryptoConstants::RSA_F4 (6537) will be used.
2. An <Integer> to just define the bits...this is shorthand for a nil exponent described
    above."

This means you generate RSA keys with either
publicKey := OSSslRSAKey createNew: 256.
or
publicKey := OSSslRSAKey createNew: 256 -> bytesE asOpenSSLBigNumber.  "<-- Convert public exponent byte array in big-endian format to number"

But you can see that this is a key generator method and uses OpenSSL's RSA_generate_key_ex function.
What your after is setting both e and n manually instead of generating n.
Typically, you would read these public values from bytes or a file using the #createNewFromFile: or #createNewFromBytes: methods where the the input is DER or PEM encoded.
If you can get the public parameters in these terms then you could use one of those methods (probably createNewFromBytes: since your doing this in memory).

There is another option but the behavior has not been officially exposed in VA.  You would need to grab the low-level RSA struct and manually set e and n.
Given that the RSA struct has gone opaque since 1.1.0, this needs to be done carefully if you need to support multiple versions.

If you want to send in a support ticket to [hidden email], I can work with you more on this.

-- Seth

On Monday, February 5, 2018 at 5:48:22 AM UTC-5, Jan van de Sandt wrote:
Hello list,

For a JSON API that we are implementing in VA Smalltalk we need to support JSON Web Tokens (JWT's). In order to validate the caller of our API we need to validate a RS256 (RSA PKCS#1 signature with SHA-256) signed JWT token.

We want to use the OpenSSL support that is shipped with VA Smalltalk to implement this. One step that we need to do is to setup a RSA public key that we retrieved as a JSON document.

An example:

The JSON document:

{
  "keys": [
    {
"kid":"X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk",
"nbf":1493763266,"use":"sig",
"kty":"RSA",
"e":"AQAB",
"n":"tVKUtcx_n9rt5afY_2WFNvU6PlFMggCatsZ3l4RjKxH0jgdLq6CScb0P3ZGXYbPzXvmmLiWZizpb-h0qup5jznOvOr-Dhw9908584BSgC83YacjWNqEK3urxhyE2jWjwRm2N95WGgb5mzE5XmZIvkvyXnn7X8dvgFPF5QwIngGsDG8LyHuJWlaDhr_EPLMW4wHvH0zZCuRMARIJmmqiMy3VD4ftq4nS5s8vJL0pVSrkuNojtokp84AtkADCDU_BUhrc2sIgfnvZ03koCQRoZmWiHu86SuJZYkDFstVTVSR0hiXudFlfQ2rOhPlpObmku68lXw-7V-P7jwrQRFfQVXw"
}
  ]
}

The "e" field contains the exponent of the RSA public key and the "n" field contains the modulo field.

First thing is to url/base64 decode the fields. Than we have two byte arrays:

| bytesE bytesN publicKey |
byestE := #[1 0 1].
bytesN := #[181 82 148 181 204 127 159 218 237 229 167 216 255 101 133 54 245 58 62 81 76 130 0 154 182 198 119 151 132 99 43 17 244 142 7 75 171 160 146 113 189 15 221 145 151 97 179 243 94 249 166 46 37 153 139 58 91 250 29 42 186 158 99 206 115 175 58 191 131 135 15 125 211 206 124 224 20 160 11 205 216 105 200 214 54 161 10 222 234 241 135 33 54 141 104 240 70 109 141 247 149 134 129 190 102 204 78 87 153 146 47 146 252 151 158 126 215 241 219 224 20 241 121 67 2 39 128 107 3 27 194 242 30 226 86 149 160 225 175 241 15 44 197 184 192 123 199 211 54 66 185 19 0 68 130 102 154 168 140 203 117 67 225 251 106 226 116 185 179 203 201 47 74 85 74 185 46 54 136 237 162 74 124 224 11 100 0 48 131 83 240 84 134 183 54 176 136 31 158 246 116 222 74 2 65 26 25 153 104 135 187 206 146 184 150 88 144 49 108 181 84 213 73 29 33 137 123 157 22 87 208 218 179 161 62 90 78 110 105 46 235 201 87 195 238 213 248 254 227 194 180 17 21 244 21 95].

"How to create a RSA public key??? -- this does not work"
publicKey := OSSslRSAKey createNewFromBytes: bytesN.

We can't figure out how to create the public key from the byte arrays. Any help would be really appriciated!

Kind regards,
Jan.





--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/va-smalltalk.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/va-smalltalk.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/va-smalltalk.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: OpenSSL - How to create a RSA public key from module and exponent values

Seth Berman
Greetings Jan,

Excellent...I’m glad that got you going.
OpenSSL does provide such setter functions, we just don’t have them wrapped.  I’ve created a development case to address this for the next release.

Kind Regards,

- Seth

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/va-smalltalk.
For more options, visit https://groups.google.com/d/optout.