I am trying to sign using pyjwt
key = jwk.JWK.from_pem(pkey_contents)
token = jwt.JWT(header={"alg": "ES256"},
claims=Token.serialize())
token.make_encrypted_token(key)
and I am getting this error
app_1 | File "/usr/local/lib/python3.6/site-packages/jwcrypto/jwe.py", line 122, in _jwa_keymgmt
app_1 | raise InvalidJWEOperation('Algorithm not allowed')
app_1 | jwcrypto.common.InvalidJWEOperation: Algorithm not allowed
Replace make_encrypted_token with make_signed_token
Make encrypted_token encrypts the end token whereas ES256 is used to sign the token.
Related
I followed former answers from Webcrypto AES-CBC Decrypt: Operation Error - The operation failed for an operation-specific reason and JavaScript AES encryption and decryption (Advanced Encryption Standard)
and used:
iv = crypto.getRandomValues(new Uint8Array(16))
key = window.crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256,
},
false,
["encrypt", "decrypt"]
)
to generate the key
and
Uint8ArrayEncrypted = window.crypto.subtle.encrypt(
{name: "aes-gcm", iv: iv, tagLength: 128},
key,
Uint8ArrayVar)
to encrypt and
Uint8ArrayDecrypted = window.crypto.subtle.decrypt(
{name: "aes-gcm", iv: iv, tagLength: 128},
key,
Uint8ArrayEncrypted)
to decrypt
On Chromium 83 (Ubuntu) and Firefox 88, I successfully generate the key, the iv and encrypt.
And on Chromium, it simply also decrypts without problem.Uint8ArrayDecrypted is correct ArrayBuffer.
But FF throws the error "The operation failed for an operation-specific reason" and stop there. No Uint8ArrayDecrypted returned.
I didn't use tag, like in WebCrypto API: DOMException: The provided data is too small
Reading https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/encrypt,
I don't see it uses tag.
Does Firefox need something else specific?
Why the error message is so "generic"? Which operation or specific reason?
With an error so generic, I don't know where to look.
I'm trying to implement RSA SHA1 signature verification.
To my surprise, command line OpenSSL tool doesn't generate the same key as the Ruby OpenSSL.
If I run those commands :
MacBook-Pro-de-Geoffrey:ssl_tests Escaflowne$ cat data.txt
000
MacBook-Pro-de-Geoffrey:ssl_tests Escaflowne$ openssl dgst -sha1 -binary -sign prvkey.pem -out sig.bin data.txt
MacBook-Pro-de-Geoffrey:ssl_tests Escaflowne$ openssl base64 -in sig.bin -out sig64.txt
MacBook-Pro-de-Geoffrey:ssl_tests Escaflowne$ cat sig64.txt
AJEh2kA7O3j624Kdl7UCGN1HiEk/v2LQudB+cjxw1CfmRTjcSPBjUE/EAwy8NEut
K4zYgfRwwTs7NY3AwYiUEtAe5yohUM0Qv17qSDW+G4IWjwe9PKE7Sl00umiMdszA
q/1hqeQlHKgjme7YO7H6i1UcAXmriOOjn+ySRaovsHw=
So final base64 result in command line is :
AJEh2kA7O3j624Kdl7UCGN1HiEk/v2LQudB+cjxw1CfmRTjcSPBjUE/EAwy8NEut
K4zYgfRwwTs7NY3AwYiUEtAe5yohUM0Qv17qSDW+G4IWjwe9PKE7Sl00umiMdszA
q/1hqeQlHKgjme7YO7H6i1UcAXmriOOjn+ySRaovsHw=
Now, if I try signing it through my ruby script :
def sign_message(message)
privkey = OpenSSL::PKey::RSA.new(File.read(Rails.root.join('lib', 'payment', 'prvkey.pem')))
digest = OpenSSL::Digest.new('sha1')
expected_sign = privkey.sign(digest, message)
base_64_expected_sign = [expected_sign].pack('m')
puts "Expected Signature"
puts expected_sign
puts "Base 64 Expected Signature"
puts base_64_expected_sign
return base_64_expected_sign
end
And calling the function like this :
def test_sign
message = "000"
message_signature = sign_message(message)
puts "Message Signature : #{message_signature}"
puts "Valid : #{verify_signature(message_signature, message)}"
end
I get the output :
Expected Signature
??|??n?^~?T_1Y#??BR??u???k x?*????S?L?:.7
t??tc?)崪? ?}DMp?p2??4?D-f??jT;!e
?k??5??
Base 64 Expected Signature
QjhL1zQoUdGFLVCMg06/CKeE/HdhRTOhJ/p09wkWeK0qD/afsxfcU7tMtDou
Nw3rwXw/5W68XhZ+BK1UXwIxWUDbFYlCUpu6HnWTmI5rC3QP+f50Y8kp5bSq
gQkekH1ETXDmcDKvExeSNKVELWYe3uwTalQ7IWUMyWvnF541rvo=
Message Signature : QjhL1zQoUdGFLVCMg06/CKeE/HdhRTOhJ/p09wkWeK0qD/afsxfcU7tMtDou
Nw3rwXw/5W68XhZ+BK1UXwIxWUDbFYlCUpu6HnWTmI5rC3QP+f50Y8kp5bSq
gQkekH1ETXDmcDKvExeSNKVELWYe3uwTalQ7IWUMyWvnF541rvo=
So final ruby OpenSSL signature is :
QjhL1zQoUdGFLVCMg06/CKeE/HdhRTOhJ/p09wkWeK0qD/afsxfcU7tMtDou
Nw3rwXw/5W68XhZ+BK1UXwIxWUDbFYlCUpu6HnWTmI5rC3QP+f50Y8kp5bSq
gQkekH1ETXDmcDKvExeSNKVELWYe3uwTalQ7IWUMyWvnF541rvo=
Versus command line :
AJEh2kA7O3j624Kdl7UCGN1HiEk/v2LQudB+cjxw1CfmRTjcSPBjUE/EAwy8NEut
K4zYgfRwwTs7NY3AwYiUEtAe5yohUM0Qv17qSDW+G4IWjwe9PKE7Sl00umiMdszA
q/1hqeQlHKgjme7YO7H6i1UcAXmriOOjn+ySRaovsHw=
I've been struggling with this for some time now and I don't understand what could be making a difference!
UPDATE :
Well, apparently results match if I replace my message variable with File.read(Rails.root.join('lib', 'payment', 'data.txt'))
So basically, using a string with the same value as what's in the text file doesn't give the same result.
This means it's encoding related right ?
UPDATE 2 :
So the file says its encoded in us-ascii if I run file -I data.txt
However, if I do message.encoding.name it says its loaded as UTF-8
Also, message.encode('ascii') does not alter the result of the generated signature, it still corresponds with the command line openssl.
As soon as I switch to a string "000".encode('utf-8') or "000".encode('ascii'), the signatures don't match anymore.
So encoding doesn't seem to play a role at all.
How come there's a difference between the exact same content whether it comes from reading a file or written as a string ?
The file data.txt has a trailing newline that you are not taking into account in your code. Using
message = "000\n"
should work.
You could also do
message = File.binread("data.txt")
to make sure you get the exact data as the command line.
I'm new in Visual Studio. I'm using Visual Studio 2015 with SpecFlow. Below is the Feature File:
#mytag
Scenario Outline: Successful Authentication
Given I am a user of type <user>
When I hit the application URL
And I provide <email>
And I click on Log In Button
Then I will be landed to the Home Page
And I will be able to see <name> on the Home Page
Examples:
| user | email | name |
| admin | a.b#example.com | alpha |
| non-admin | b.c#example.com | beta |
When I generate the step definitions I'm expecting parameters in place of the variables, instead the method is generated as below:
[Given(#"I am a user of type admin")]
public void GivenIAmAUserOfTypeAdmin()
{
ScenarioContext.Current.Pending();
}
I was instead expecting a method like:
[Given(#"I am a user of type '(.*)'")]
public void GivenIAmAUserOfType(string p0)
{
ScenarioContext.Current.Pending();
}
What am I missing?
As an example, surrounding the <user> in the Given step with '' like this,
Given I am a user of type '<user>'
will generate the desired results. It's probably needed in order to recognize the regular expression.
I'd like to get different pointe of views about how to create integration tests for Rest APIs.
The first option would be using cucumber as described in the "The Cucumber Book":
Scenario: Get person
Given The system knows about the following person:
| fname | lname | address | zipcode |
| Luca | Brow | 1, Test | 098716 |
When the client requests GET /person/(\d+)
Then the response should be JSON:
"""
{
"fname": "Luca",
"lname": "Brow",
"address": {
"first": "1, Test",
"zipcode": "098716"
}
}
"""
The second option would be (again) using cucumber, but removing the technical detail as described here:
Scenario: Get person
Given The system knows about the following person:
| fname | lname | address | zipcode |
| Luca | Brow | 1, Test | 098716 |
When the client requests the person
Then the response contains the following attributes:
| fname | Luca |
| lname | Brow |
| address :first | 1, Test |
| address :zipcode | 098716 |
And the third option would be using Spring as described here:
private MockMvc mockMvc;
#Test
public void findAll() throws Exception {
mockMvc.perform(get("/person/1"))
.andExpect(status().isOk())
.andExpect(content().mimeType(IntegrationTestUtil.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.fname", is("Luca")))
.andExpect(jsonPath("$.lname", is("Brow")))
.andExpect(jsonPath("$.address.first", is("1, Test")))
.andExpect(jsonPath("$.address.zipcode", is("098716")));
}
I really like the second option since it looks cleaner to business users and testers, but on the other hand for a developer that will consume this API the first option looks more visible since it shows the JSON response.
The third option is the easiest one since it's just Java code, but the readability and the cross-team interaction is not as nice as cucumber.
You should use the third option but not with junit, you should do it using spock.This is the best of both the worlds.
Spock tests are written like this
def "description of what you want to test"() {
given:
//Do what is pre-requisite to the test
when:
def response = mockMvc.perform(get("/person/id")).andReturn().getResponse();
then:
checkForResponse.each {
c->c(response )
}
where:
id | checkResponse
1 | [ResponseChecker.correctPersondetails()]
100 | [ResponseChecker.incorrectPersondetails()]
}
Integration test are made to test if components of your application can work together. For example, you test some requests to database and mvc controller with integration tests. Integration tests are here to test your infrastructure.
On the other hand, BDD tests are made to facilitate communication between development and specifications. The common idea is to write tests or specification by example. There are definitely not design to write integration tests.
I would recommend the third option.
I use Spring Security persistent logins. I persist the remember me token in my database. Sometimes I get the following error:
| Error 2013-07-02 13:54:14,859 [http-nio-8080-exec-2] ERROR [/buddyis].[gsp] -
Servlet.service() for servlet [gsp] in context with path [/buddyis] threw exception
Message: Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack.
Line | Method
->> 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . in java.lang.Thread
In my Config.groovy:
grails.plugins.springsecurity.logout.handlerNames = [
'rememberMeServices', 'securityContextLogoutHandler', 'mySecurityEventListener'
]
grails.plugins.springsecurity.rememberMe.cookieName = 'RememberMe'
grails.plugins.springsecurity.rememberMe.alwaysRemember = true
grails.plugins.springsecurity.rememberMe.tokenValiditySeconds = 31536000 // 365 days
grails.plugins.springsecurity.rememberMe.key = 'rememberMe'
grails.plugins.springsecurity.rememberMe.persistent = true
grails.plugins.springsecurity.rememberMe.persistentToken.domainClassName = 'mypackage.PersistentLogin'
How do I fix this error? What does it mean?
I am having the same exception in my mobile web site.
When the http session of the user who has logged in with remember me expires and when the user access the web site again, if there are multiple parallel (ajax) requests this issue occurs.
It happens because the first of the parallel requests will refresh the remember me token and the token (which is invalidated) all the other request(s) will have mismatch the persisted token.
So you don't have many options to fix this, an option is to not have parallel requests, but in toady's mobile apps it is not much possible.
What i did is to have /me requests which is the first thing i make upon launching/loading the web app and after that i can do multiple parallel requests without worrying that i will hit this issue.