英文:
Generate shopify multipass token
问题
我正在尝试在Perl中生成Shopify的多通行令牌,但一直收到无效请求的响应。
我的客户数据如下:
{ "email": "randomEmail@gmail.com", "last_name": "last_name", "first_name": "first_name" }
我已确认以下内容是有效的:
- 客户数据格式和信息
- API密钥
- 商店网址
- 加密和签名密钥
- 时间格式是UTC
这是我目前的实现:
sub generate_multipass_token {
use JSON qw(encode_json);
use MIME::Base64 qw(encode_base64);
use Digest::SHA qw(sha256 hmac_sha256);
use Crypt::CBC;
use Crypt::Cipher::AES;
use POSIX qw(strftime);
use Encode qw(encode);
my ($customer_data) = @_;
my $store_api_key = '';
my $store_url = '';
my $hash = sha256($store_api_key);
my $encryption_key = substr($hash, 0, 16);
my $signing_key = substr($hash, 16, 16);
my ($sec, $min, $hour, $day, $mon, $year) = gmtime();
my $formatted_time = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", $year+1900, $mon+1, $day, $hour, $min, $sec);
# 将格式化时间添加到客户数据中
$customer_data->{'created_at'} = $formatted_time;
# 将客户数据进行JSON编码
my $json_customer_data = encode_json($customer_data);
# 使用AES加密客户数据
my $iv = Crypt::CBC->random_bytes(16);
my $cipher = Crypt::CBC->new(
-key => $encryption_key,
-iv => $iv,
-cipher => 'Cipher::AES',
-header => 'none',
);
my $encrypted_data = $cipher->encrypt($json_customer_data);
$encrypted_data = $iv . $encrypted_data;
my $signature = hmac_sha256($encrypted_data, $signing_key);
my $token = encode_base64url($encrypted_data . $signature);
return "$store_url/account/login/multipass/" . $token;
}
sub encode_base64url {
my $data = shift;
my $encoded = encode_base64($data, '');
$encoded =~ tr{+/}{-_};
$encoded =~ s/=+$//;
return $encoded;
}
我已经使用Python的spylib测试了商店信息,并且能够在那里生成有效的令牌,当比较变量时,令牌长度最终相同(可以尝试注释掉时间来检查这一点)。
我不确定我到底哪里出错了,PHP的等效方式(https://shopify.dev/docs/api/multipass)与我的实现非常相似。我认为问题可能与加密有关,但无法确定具体原因。
英文:
I'm trying to generate a shopify multipass token in Perl but keep getting invalid request responses.
My customer data consists of :
{"email": "randomEmail@gmail.com", "last_name": "last_name", "first_name": "first_name"}
Things I've certified as valid:
- Customer data format and information
- API key
- Store URL
- Encryption and signing keys
- Time format is in UTC
Here is the current implementation I have
sub generate_multipass_token {
use JSON qw(encode_json);
use MIME::Base64 qw(encode_base64);
use Digest::SHA qw(sha256 hmac_sha256);
use Crypt::CBC;
use Crypt::Cipher::AES;
use POSIX qw(strftime);
use Encode qw(encode);
my ($customer_data) = @_;
my $store_api_key = '';
my $store_url = '';
my $hash = sha256($store_api_key);
my $encryption_key = substr($hash, 0, 16);
my $signing_key = substr($hash, 16, 16);
my ($sec, $min, $hour, $day, $mon, $year) = gmtime();
my $formatted_time = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", $year+1900, $mon+1, $day, $hour, $min, $sec);
# Add the formatted time to the customer data
$customer_data->{created_at} = $formatted_time;
# JSON-encode the customer data
my $json_customer_data = encode_json($customer_data);
# Encrypt the customer data using AES
my $iv = Crypt::CBC->random_bytes(16);
my $cipher = Crypt::CBC->new(
-key => $encryption_key,
-iv => $iv,
-cipher => 'Cipher::AES',
-header => 'none',
);
my $encrypted_data = $cipher->encrypt($json_customer_data);
$encrypted_data = $iv . $encrypted_data;
my $signature = hmac_sha256($encrypted_data, $signing_key);
my $token = encode_base64url($encrypted_data . $signature);
return "$store_url/account/login/multipass/" . $token;
}
sub encode_base64url {
my $data = shift;
my $encoded = encode_base64($data, '');
$encoded =~ tr{+/}{-_};
$encoded =~ s/=+$//;
return $encoded;
}
I have used python's spylib to test the store information and was able to generate a valid token there, when comparing variables, the token length ends up to the same length (commenting out the time to check this).
I'm not sure where I'm going wrong, the php equivalent https://shopify.dev/docs/api/multipass is very similar to my implementation. I'm thinking it might be something with the encryption but can't tell what.
答案1
得分: 1
需要进行的更改是:
my $cipher = Crypt::CBC->new(
-key => $encryption_key,
-iv => $iv,
-cipher => 'OpenSSL::AES',
-header => 'none',
-literal_key => 1,
-keysize => 128/8
);
英文:
Change needed was:
my $cipher = Crypt::CBC->new(
-key => $encryption_key,
-iv => $iv,
-cipher => 'OpenSSL::AES',
-header => 'none',
-literal_key => 1,
-keysize => 128/8
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论