質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio 2010

Microsoft Visual Studio 2010はMicrosoftが提供している統合開発環境(IDE)です。

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

2回答

1620閲覧

Yahooショッピング 注文APIの公開鍵認証を実装したい

hal2023

総合スコア1

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio 2010

Microsoft Visual Studio 2010はMicrosoftが提供している統合開発環境(IDE)です。

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

1クリップ

投稿2023/08/08 07:22

編集2023/08/09 17:42

実現したいこと

Yahooショッピング 注文APIにて、「公開鍵で暗号化した認証情報をAPIリクエストヘッダに付加してリクエスト」をVB.NETにて実装

認証手順
1.公開鍵ファイルを作成
公開鍵の内容はYahooショッピング管理コンソールにて発行
内容をコピーし、public.keyというファイル名でファイル作成
<公開鍵内容例>
-----BEGIN PUBLIC KEY-----
ABCfMA0GCSqGSIb...6txJ/YUbwIDACBA
-----END PUBLIC KEY-----
2.認証情報の作成
ストアアカウントとunixtimestampを:で結合した情報を作成
3.認証情報を公開鍵で暗号化
認証情報を公開鍵で暗号化(PKCS1PADDING)し、BASE64エンコード
4.暗号化した認証情報をAPIリクエストヘッダに付加してリクエスト

前提

・認証情報がなくてもエラーとはならない。
・APIリクエスト・レスポンスは、認証なしでも問題なくできている。

発生している問題・エラーメッセージ

・下記のコードを実行した場合、
レスポンスヘッダー取得「X-SWS-Authorize-Status」にて、「unauthorized」のレスポンスが返る。
※成功すれば、「authorized」が返る

該当のソースコード

VB.NET

1 ' UTF-8でエンコードする 2 Dim enc As Encoding = New UTF8Encoding() 3 4 'WebAPI暗号鍵処理 5 'ストアクリエイターPro上で発行した公開鍵のパス 6 Dim keyFilePath As String = String.Format("{0}/key/{1}", sCurrentDir, PUBLICKEYFILENM) 7 8 '現在日時取得(unixtimestamp取得) 9 Dim unixTime As Long = GetUnixTime(DateTime.Now) 10    ⇒GetUnixTimeメソッドは最下部に記載 11 12 '認証情報作成(ストアアカウントとunixtimestampを:で結合する) 13 Dim authenticationValue As String = String.Format("{0}:{1}", STOREACCOUNT, unixTime) 14 15 'pem形式の公開鍵読み込み 16 '読み込むファイル 17 Dim textFile As String = keyFilePath 18 'テキストファイルの中身をすべて読み込む 19 Dim publicKeyPem As String = System.IO.File.ReadAllText(textFile, enc) 20 21 '不要部分を削除 22 publicKeyPem = Replace(publicKeyPem, "-----BEGIN PUBLIC KEY-----" & vbCrLf, String.Empty) 23 publicKeyPem = Replace(publicKeyPem, "-----END PUBLIC KEY-----", String.Empty) 24 publicKeyPem = Replace(publicKeyPem, vbLf, String.Empty) 25 26 '公開鍵と秘密鍵を取得 27 Dim privateKey As String = publicKeyPem 28 Dim publicKey As String = publicKeyPem 29 CreateKeys(PublicKey, privateKey) 30    ⇒CreateKeysメソッドは最下部に記載 31 32 '認証情報の暗号化 33 Dim encodedAuthenticationValue As String = Encrypt(authenticationValue, publicKey) 34    ⇒Encryptメソッドは最下部に記載 35 36 'POST送信する文字列を作成 37 Dim postData As String = _ 38 GetRequestXMLData_OrderList(iGetOrderMaxCnt, sIsSeen, Format(Now.AddDays(-iOrderGetPeriod), "yyyyMMddHHmmss"), Format(Now, "yyyyMMddHHmmss"), "1,2", STOREACCOUNT) 39    ⇒GetRequestXMLData_OrderListメソッドは今回の問題点とは関係ないため未記載 40 41 'バイト型配列に変換 42 Dim postDataBytes As Byte() = _ 43 System.Text.Encoding.UTF8.GetBytes(postData) 44 45 'TLS1.2での通信対応 46 ServicePointManager.SecurityProtocol = DirectCast(3072, SecurityProtocolType) 47 48 'WebRequestの作成 49 Dim req As System.Net.HttpWebRequest = _ 50 System.Net.HttpWebRequest.Create(YAHOOAPI_ORDERLISTURL) 51 52 'アクセストークン取得 53 sAccessToken = Get_AccessToken() 54    ⇒Get_AccessTokenメソッドは今回の問題点とは関係ないため未記載 55 56 'ヘッダ指定 57 req.Headers.Add("Authorization: Bearer " & sAccessToken) 58 req.Headers.Add("X-sws-signature: " & encodedAuthenticationValue) '暗号化した認証情報 59 req.Headers.Add("X-sws-signature-version: 1") '取得した公開鍵のバージョン 60 61 'メソッドにPOSTを指定 62 req.Method = "POST" 63 'ContentTypeを"application/x-www-form-urlencoded"にする 64 req.ContentType = "application/x-www-form-urlencoded" 65 66 'POST送信するデータの長さを指定 67 req.ContentLength = postDataBytes.Length 68 69 'データをPOST送信するためのStreamを取得 70 Dim reqStream As System.IO.Stream = req.GetRequestStream() 71 '送信するデータを書き込む 72 reqStream.Write(postDataBytes, 0, postDataBytes.Length) 73 reqStream.Close() 74 75 'サーバーからの応答を受信するためのWebResponseを取得 76 Dim res As System.Net.HttpWebResponse = req.GetResponse() 77 'レスポンスヘッダー取得「X-SWS-Authorize-Status」 78 For i As Integer = 0 To res.Headers.Count - 1 79 If res.Headers.Keys(i) = "X-Sws-Authorize-Status" Then 80 If res.Headers(i) <> "authorized" Then 81 'エラー 82 End If 83 Exit For 84 End If 85 Next 86 87 '応答データを受信するためのStreamを取得 88 Dim resStream As System.IO.Stream = res.GetResponseStream() 89 '受信して表示 90 Dim sr As New System.IO.StreamReader(resStream, enc) 91 Dim sInfo As String = sr.ReadToEnd() 92 93 '閉じる 94 sr.Close() 95 96 ''' <summary> 97 ''' UNIXTIMESTAMP取得 98 ''' </summary> 99 ''' <param name="targetTime"></param> 100 ''' <returns></returns> 101 ''' <remarks></remarks> 102 Public Shared Function GetUnixTime(ByVal targetTime As DateTime) As Long 103 ' UNIXエポックを表すDateTimeオブジェクトを取得 104 Dim UNIX_EPOCH As DateTime = New DateTime(1970, 1, 1, 0, 0, 0, 0) 105 106 ' UTC時間に変換 107 targetTime = targetTime.ToUniversalTime() 108 109 ' UNIXエポックからの経過時間を取得 110 Dim elapsedTime As TimeSpan = targetTime - UNIX_EPOCH 111 112 ' 経過秒数に変換 113 Return CType(elapsedTime.TotalSeconds, Long) 114 115 End Function 116 117 ''' <summary> 118 ''' 公開鍵と秘密鍵を作成して返す 119 ''' </summary> 120 ''' <param name="publicKey">作成された公開鍵(XML形式)</param> 121 ''' <param name="privateKey">作成された秘密鍵(XML形式)</param> 122 Public Shared Sub CreateKeys(ByRef publicKey As String, _ 123 ByRef privateKey As String) 124 'RSACryptoServiceProviderオブジェクトの作成 125 Dim rsa As New System.Security.Cryptography.RSACryptoServiceProvider() 126 127 '公開鍵をXML形式で取得 128 publicKey = rsa.ToXmlString(False) 129 '秘密鍵をXML形式で取得 130 privateKey = rsa.ToXmlString(True) 131 End Sub 132 133 ''' <summary> 134 ''' 公開鍵を使って文字列を暗号化する 135 ''' </summary> 136 ''' <param name="str">暗号化する文字列</param> 137 ''' <param name="publicKey">暗号化に使用する公開鍵(XML形式)</param> 138 ''' <returns>暗号化された文字列</returns> 139 Public Shared Function Encrypt(ByVal str As String, _ 140 ByVal publicKey As String) As String 141 'RSACryptoServiceProviderオブジェクトの作成 142 Dim rsa As New System.Security.Cryptography.RSACryptoServiceProvider() 143 144 '公開鍵を指定 145 rsa.FromXmlString(publicKey) 146 147 '暗号化する文字列をバイト配列に 148 Dim data As Byte() = System.Text.Encoding.UTF8.GetBytes(str) 149 '暗号化する 150 '(XP以降の場合のみ2項目にTrueを指定し、OAEPパディングを使用できる) 151 Dim encryptedData As Byte() = rsa.Encrypt(data, False) 152 153 'Base64で結果を文字列に変換 154 Return System.Convert.ToBase64String(encryptedData) 155 End Function

様々なサイトを参考にしましたが、手詰まり状態です。
お気づきの点等ありましたらご指摘・ご教授頂けるとありがたいです。
※VB.NETは”.Net Framework4.0”を使用

参考サイト

公開鍵暗号方法で暗号化する

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2023/08/08 08:53

参考にしたサイトを質問本文に追記ください。
guest

回答2

0

ベストアンサー

コードをみる限り、公開鍵ファイルの内容が正しく利用されておらずランダムなキーで暗号化しているように思います。
RSA.ImportFromPemでPEM形式の文字列から読み込むと正しい鍵で暗号化できると思います。
以下、Chat-GPTが回答したC#でのサンプルコードです(動作未確認です)。

C#

1using System; 2using System.Security.Cryptography; 3using System.Text; 4 5class Program 6{ 7 static void Main() 8 { 9 // PEM形式の公開鍵を文字列から読み込む 10 string publicKeyPem = @"-----BEGIN PUBLIC KEY----- 11 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5e1RvIu42W23S3yJ/FNV 12 wQx7DZz7Lqyq1NifUj6z2tm4og3nYsz5fhrKXbTixum+Oj5pOzTdN2JwIhRNCNXG 13 CYS9ftH09s3pPEUJaxpEFw7KUg0mjBGM4UDgIQjElDQIjMzCmmlnkOYNfu3gz+51 14 0OD6A4L/OdfbnoFsFawL4Kh9NV65zUKhlgX5SBBpPS9EpS0gs5+kMfUv+a6yZpBQ 15 V3FlQ+IyY2K7x1sSi4AEJzKMGTU/JiGmZYnh8IT9fGRH6Ndn25ZxnOnv/bHyR+p2 16 hQHygIt4fL3lf9TibTQtUMgfnzFDr67O3SZnCBmc8Qz30JTtqxCbNAp7r1oDlS9Q 17 BQIDAQAB 18 -----END PUBLIC KEY-----"; 19 20 string inputText = "Hello, encryption!"; 21 22 using (RSA rsa = RSA.Create()) 23 { 24 // PEM形式の公開鍵をインポート 25 rsa.ImportFromPem(publicKeyPem); 26 27 // 公開鍵を使用して文字列を暗号化 28 byte[] encryptedBytes = rsa.Encrypt(Encoding.UTF8.GetBytes(inputText), RSAEncryptionPadding.Pkcs1); 29 Console.WriteLine("Encrypted Text: " + Convert.ToBase64String(encryptedBytes)); 30 } 31 } 32}

また、Importing RSA public keys in downlevel .NET and .NET Framework versionsに古い.NETでの代替手段(コード)が示されています。
おおまかにPEM(テキスト)からDER(バイナリ)を作ってRSAPublicKeyというものでインポートするようですが、これが利用できるかもしれません。

投稿2023/08/08 08:52

編集2023/08/09 10:04
can110

総合スコア38339

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hal2023

2023/08/09 09:23 編集

回答ありがとうございます。 VB.NET(.Net Framework4.0)では、 ``` rsa.ImportFromPem ``` が使用できず、公開鍵のPEM形式のインポートができておりません。 プログラム言語 or .NetFrameworkの限界かと思っております。 環境の変更はできませんので、どのように対応しようか悩んでおります。
can110

2023/08/09 09:51

質問に代替手段について追記しました。 なお、すでに参考にされたサイトがあれば質問本文への追記願います。 後に同じような問題を解決したい人の役に立つかもしれないので。
hal2023

2023/08/16 00:33

本件の問題点、参考サイト提示の教示ありがとうございます。 本件解決いたしましたので、感謝申し上げます。
guest

0

本件、解決いたしました。
事例共有のため、以下に記載いたします。

BouncyCastleライブラリを使用することで実現いたしました。
外部より「BouncyCastle.Crypto.dll」をダウンロードし、インポートしています。

VB.NET

1Imports Org.BouncyCastle.OpenSsl 2Imports Org.BouncyCastle.Crypto 3Imports Org.BouncyCastle.Crypto.Engines 4Imports Org.BouncyCastle.Crypto.Encodings 5 6 ' UTF-8でエンコードする 7 Dim enc As Encoding = New UTF8Encoding() 8 9 '暗号化処理 ------------------------------------------------------------------- start 10 'WebAPI暗号鍵処理 11 'ストアクリエイターPro上で発行した公開鍵のパス 12 Dim keyFilePath As String = String.Format("{0}/key/{1}", sCurrentDir, PUBLICKEYFILENM) 13 14 '現在日時取得(unixtimestamp取得) 15 Dim unixTime As Long = GetUnixTime(DateTime.Now) 16 17 '認証情報作成(ストアアカウントとunixtimestampを:で結合する) 18 Dim authenticationValue As String = String.Format("{0}:{1}", STOREACCOUNT, unixTime) 19 Dim authenticationByte As Byte() = System.Text.Encoding.UTF8.GetBytes(authenticationValue) 20 21 'pem形式の公開鍵読み込み 22 '読み込むファイル 23 Dim textFile As String = keyFilePath 24 'テキストファイルの中身を読み込む 25 Dim publicKeyPem As StreamReader = New StreamReader(textFile, enc) 26 27 'PEMフォーマットの公開鍵を読み込んで KeyParam を生成 28 Dim publicKeyReader As New PemReader(publicKeyPem) 29 Dim publicKeyParam As AsymmetricKeyParameter = publicKeyReader.ReadObject() 30 31 'RSA暗号標準オブジェクト(PKCS#1)を生成 32 Dim rsa As New Pkcs1Encoding(New RsaEngine()) 33 'RSA暗号オブジェクトを初期化(第1引数 true は「暗号化」を示す) 34 rsa.Init(True, publicKeyParam) 35 36 '対象のバイト列を渡し暗号化した結果のバイト列を受け取る 37 Dim encrypted As Byte() = rsa.ProcessBlock(authenticationByte, 0, authenticationByte.Length) 38 39 'Base64で結果を文字列に変換 40 Dim encodedAuthenticationValue As String = System.Convert.ToBase64String(encrypted) 41 '暗号化処理 ------------------------------------------------------------------- end 42 43 'POST送信する文字列を作成 44 Dim postData As String = _ 45 GetRequestXMLData_OrderInfo(sOrderId(0), STOREACCOUNT) 46 47 'バイト型配列に変換 48 Dim postDataBytes As Byte() = _ 49 System.Text.Encoding.ASCII.GetBytes(postData) 50 51 'TLS1.2での通信対応 52 ServicePointManager.SecurityProtocol = DirectCast(3072, SecurityProtocolType) 53 54 'WebRequestの作成 55 Dim req As System.Net.HttpWebRequest = _ 56 System.Net.HttpWebRequest.Create(YAHOOAPI_ORDERINFOURL) 57 58 'ヘッダ指定 59 req.Headers.Add("Authorization: Bearer " & sAccessToken) 60 req.Headers.Add("X-sws-signature: " & encodedAuthenticationValue) '暗号化した認証情報 61 req.Headers.Add("X-sws-signature-version: 1") '取得した公開鍵のバージョン 62 63 ---------- 以下、質問内容と同じコードのため省略 -------------

参考サイト

https://qiita.com/snaka/items/0829c37494b61353445e

開発環境

VisualStudio2010
VB.NET

動作環境

.Net Framework4.0

開発、作業に関して

・Windowsフォームアプリケーションよりexeファイルを作成
・VisualStudio2010使用のため、ライブラリをNuGetできず、他Ver.VSにてDLしたdllファイルをインポート

投稿2023/08/16 00:29

編集2023/08/16 00:35
hal2023

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問