生成 Shopify 多通行令牌。

huangapple go评论57阅读模式
英文:

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
);

huangapple
  • 本文由 发表于 2023年2月24日 08:58:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75551738.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定