PKCS7(CMS)で同じ応答xml署名を使用して複数の場所に署名します

3
Urmi_VV_Developer 2019-03-19 09:22.

PDFドキュメントは国のデジタルIDで署名する必要があります。
National Digital Identity WebServiceは、ドキュメントに署名する機能を提供します。私のプロジェクトでは、同じものを統合しました。

Esignサービスを要求すると、PKCS7(CMS)形式で応答が返されます。複数の場所に同じ応答を追加したいので、サービスから応答を受け取った後、複数の空の署名コンテナを作成しています。

私はこの記事を参照しました:ITextSharpとXML署名を使用してPDFに署名する

しかし、与えられた記事では、署名場所は1つしかありませんが、複数の署名場所があります。

itextシャープライブラリを使用しています。MakeSignature.SignDeferredメソッドを使用して複数の場所に署名を追加していますが、PDFが無効であると表示されています。

Webサービスから受け取った応答XMLを以下に示します。

<?xml version="1.0" encoding="UTF-8"?>
<EsignResp errCode="NA" errMsg="NA" resCode="259A52453BE95D3A1071193995E062E3EAD796AD" status="1" ts="2019-03-18T14:26:59" txn="UKC:eSign:2998:20190318142602814">
    <UserX509Certificate>--Usercerti in base64--</UserX509Certificate>
    <Signatures>
        <DocSignature error="" id="1" sigHashAlgorithm="SHA256">--Signature in base 64 in PKCS7(CMS)---</DocSignature>
    </Signatures>
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod>
            <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></SignatureMethod>
            <Reference URI="">
                <Transforms>
                    <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
                <DigestValue>MrOfovytOIp/8qlEkgamrcyhGTSGTN5aS1P+08Fbwfk=</DigestValue>
            </Reference>
        </SignedInfo>
        <SignatureValue>BBexJyk47YaTdoDgXaFRCtJq1Gc3KsZNt48/I8X4TgNJ6gh2NI9Y5Y9Tc7bozrK/QRy1VYPOWYq5r/YdunjMQLmJJicyeqeqe2eD+TJ8oecpjCbmhPnDK2VgaJ2h00sfsfdsflIe/toKwAmV4PTBA1a5wkz77hj+HTkWXMkPEIsBUnBirVpHxe2bYaa7jcIIpWtJmqvcSurKTOeyFRa+AFWfwWHB/EzHJlDmgiMXzrNauxJ4HpphNaRU+bO5JdyzJs/8Zx4i6qwSEybkuprL3GdO9C7zMPiC98CTfO2dfUrbZWy1pSvwEqlVXQIfrkp+m2JRbFgT8EEIGfXUS+AJBPRwhY1Xsww==</SignatureValue>
        <KeyInfo>
            <KeyValue>
                <RSAKeyValue>
                    <Modulus>0o9vohWZ3ztI9ea8D/zUEUBRq6c82BE7sFmr1hNMeuGSJQFf39ceesRtGUzlUYVWXcU23P8sVZ5419CHh7ApFzUXaLD72i/2d5FFI0n3iRlTQec9PEUHyrvOCVDpqBhbnrO/EHBqRluUQJTQUtMu5mhPNFV7IIJMTEAsUhCL9adZXXQK9NeK0foRr29Oq7VdEGfSeLzHIibpQmhNPh89oJXqu0cmbNSW4J4i2GmwHQpmsmHaSQcgh4mgVrykO64pAKXPreAPipDHQM1l/e5hilYlWfLHxhC5OdfdfdsbTCTcydQ218IVulFOFhdQt7xVV61TOmoTC2elhWbDqoLJBVU5mBfQ==</Modulus>
                    <Exponent>AQAB</Exponent>
                </RSAKeyValue>
            </KeyValue>
            <X509Data>
                <X509SubjectName>CN=D-Random detail</X509SubjectName>
                <X509Certificate>--public certificate of provider--- </X509Certificate>
            </X509Data>
        </KeyInfo>
    </Signature>
</EsignResp>

編集:最新の通信によると、Webサービスは私の側から提供されているハッシュに対して応答を提供します。彼らはそれを検証しません。ハッシュは任意の64文字の文字列です。これを使用してPDFドキュメントにPKCS7署名を追加するための可能な方法を教えてください。

リクエストを生成するための以下のコード:

if (System.IO.File.Exists(tempPdf))
System.IO.File.Delete(tempPdf);

using (PdfReader reader = new PdfReader(pdfReadServerPath))
{
    using (FileStream os = System.IO.File.OpenWrite(tempPdf))
    {
        PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0',null,true);

        PdfSignatureAppearance appearance = stamper.SignatureAppearance;

        appearance.SetVisibleSignature(new Rectangle(15, 15, 100, 100), 1, "sign1");

        appearance.CertificationLevel = PdfSignatureAppearance.NOT_CERTIFIED;
         AllPagesSignatureContainer external = new AllPagesSignatureContainer(appearance);

        MakeSignature.SignExternalContainer(appearance, external, 8192);
        Stream data = appearance.GetRangeStream();

       Stream data = appearance.GetRangeStream();
        byte[] hash = ReadFully(data); //Convert stream to byte
        _signatureHash = hash;


    }
}
//create sha256 message digest
using (SHA256.Create())
{
    _signatureHash = SHA256.Create().ComputeHash(_signatureHash);
}
bool check = false;
string hexencodedDigest = null;
//create hex encoded sha256 message digest
hexencodedDigest = new BigInteger(1, _signatureHash).ToString(16);
hexencodedDigest = hexencodedDigest.ToUpper();
if (hexencodedDigest.Length == 64)
{
    **Send this hexencoded hash to webservice**
}

署名を追加するための以下のコード:

//DLL Call
eSign2_1_Request_Response req_resp = new eSign2_1_Request_Response();

//// Response XML Digest process
string resp_xml = Request.Form["msg"].ToString();//signature response XML;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(resp_xml);
XmlElement EsignResp = xmlDoc.DocumentElement;
if (EsignResp.Attributes != null && EsignResp.Attributes["status"].Value != "1")
{
    req_resp.WriteTextFileLog("errCode: " + EsignResp.Attributes["errCode"].Value + " & Error Message: " + EsignResp.Attributes["errMsg"].Value, "log", base_folder_path);
}
else
{
    req_resp.WriteTextFileLog(resp_xml, "xml", base_folder_path + "\\" + file_withoutExtn + "_responseXML.txt");
    //-------Continue to generate signed PDF by passing parameter to DLL

    XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signatures");

    string signature = nodeList[0].FirstChild.InnerText;

    string signedPdf = @"D:\POC Hosted\TryNSDL\TryNSDL\wwwroot\TempPath\signedPdf.pdf";
    string tempPdf = @"D:\POC Hosted\TryNSDL\TryNSDL\wwwroot\TempPath\tempPdf.pdf";
    using (PdfReader reader = new PdfReader(tempPdf))
    {

        using (FileStream os = System.IO.File.OpenWrite(signedPdf))
        {
            byte[] encodedSignature = Convert.FromBase64String(signature);

            IExternalSignatureContainer external = new MyExternalSignatureContainer(encodedSignature);

            MakeSignature.SignDeferred(reader, "sign1", os, external);
        }
    }
}

Allsignatureコンテナのコー​​ド:

public class AllPagesSignatureContainer : IExternalSignatureContainer
{
    public AllPagesSignatureContainer(PdfSignatureAppearance appearance)
    {
        this.appearance = appearance;

    }

    public void ModifySigningDictionary(PdfDictionary signDic)
    {
        signDic.Put(PdfName.FILTER, PdfName.ADOBE_PPKMS);
        signDic.Put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_DETACHED);

        PdfStamper stamper = appearance.Stamper;
        PdfReader reader = stamper.Reader;
        PdfDictionary xobject1 = new PdfDictionary();
        PdfDictionary xobject2 = new PdfDictionary();
        xobject1.Put(PdfName.N, appearance.GetAppearance().IndirectReference);
        xobject2.Put(PdfName.AP, xobject1);

        PdfIndirectReference PRef = stamper.Writer.PdfIndirectReference;
        PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + reader.NumberOfPages) + " 0 R");

        for (int i = 2; i < reader.NumberOfPages+1; i++)
        {
            var signatureField = PdfFormField.CreateSignature(stamper.Writer);

            signatureField.Put(PdfName.T, new PdfString("ClientSignature_" + i.ToString()));
            signatureField.Put(PdfName.V, PRefLiteral);
            signatureField.Put(PdfName.F, new PdfNumber("132"));
            signatureField.SetWidget(new Rectangle(15, 15, 100, 100), null);
            signatureField.Put(PdfName.SUBTYPE, PdfName.WIDGET);

            signatureField.Put(PdfName.AP, xobject1);
            signatureField.SetPage();
            Console.WriteLine(signatureField);

            stamper.AddAnnotation(signatureField, i);
        }
    }

    public byte[] Sign(Stream data)
    {
       return new byte[0];
    }

    PdfSignatureAppearance appearance;

}

署名の作成で追加モードを使用しましたが、署名がありません。空の署名のみがAdobeReaderに表示されます:/ Fileremoved /

appendmodeなしで同じことを試してみてPdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + 1 + 2 * (reader.NumberOfPages - 1)) + " 0 R");それが正常に機能する場合:/ Fileremoved /ですが、単一の署名者にのみ使用できます。もう一度同じpdfを使用して辞任しようとすると、古い署名は無効になります。(明らかに、追加モードが使用されていないためです。)

追加モードで署名を機能させるには、次の行で変更が必要PdfLiteralだと思います-実際にどのように機能するかについてはあまりわかりません。

署名されたファイル:/ Fileremoved /入力ファイル:/ Fileremoved /

1 answers

4
mkl 2019-03-20 01:23.

コードを最初にざっと見てみると、2つの大きなエラーが明らかになりました。

2回のハッシュ

ドキュメントデータを2回ハッシュします(そのために異なるAPIを使用します...奇妙です!):

        Stream data = appearance.GetRangeStream();

        byte[] hash = DigestAlgorithms.Digest(data, "SHA256");

        [...]

        _signatureHash = hash;// signatureHash;
    }
}

[...]
using (SHA256.Create())
{
    _signatureHash = SHA256.Create().ComputeHash(_signatureHash);
}

これは間違っています、これは意味がありません。

間違った署名コンテナを挿入する

あなたは言う

Esignサービスを要求すると、PKCS7(CMS)形式で応答が返されます。

ただし、結果からCMS署名コンテナを使用する代わりに、独自のCMSコンテナを構築して、単なる署名付きハッシュであるかのようにEsign応答CMSコンテナを挿入しようとします。

XmlNodeList UserX509Certificate = xmlDoc.GetElementsByTagName("UserX509Certificate");
byte[] rawdat = Convert.FromBase64String(UserX509Certificate[0].InnerText);
var chain = new List<Org.BouncyCastle.X509.X509Certificate>
{
    Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(new X509Certificate2(rawdat))
};
var signaturee = new PdfPKCS7(null, chain, "SHA256", false);
_signature = signaturee;

_signature.SetExternalDigest(Convert.FromBase64String(signature), null, "RSA");

byte[] encodedSignature = _signature.GetEncodedPKCS7(_hash, null, null, null, CryptoStandard.CMS);

XMLのコメントによると

    <DocSignature error="" id="1" sigHashAlgorithm="SHA256">--Signature in base 64 in PKCS7(CMS)---</DocSignature>

このDocSignature要素には、CMS署名コンテナが含まれています。

したがって、上記のコードセグメントを削除し、代わりにDocSignature要素のコンテンツ(base64デコードを忘れないでください)をに入れますbyte[] encodedSignature。これで、前と同じように、準備した署名にそれを挿入できます。

IExternalSignatureContainer external = new MyExternalSignatureContainer(encodedSignature);

MakeSignature.SignDeferred(reader, "sign1", os, external);

上記の問題を修正した後、さらに2つが明らかになりました。

間違ったファイルモードを使用する

ストリームを開いて、次のように書き込みます。

using (FileStream os = System.IO.File.OpenWrite(signedPdf))

File.OpenWriteさdocs.microsoft.comに文書化します

FileStream(String, FileMode, FileAccess, FileShare)ファイルモードがに設定されOpenOrCreate、アクセスがに設定されWrite、共有モードがに設定されたコンストラクターのオーバーロードに相当しますNone

次に、ファイルモードOpenOrCreateが文書化されて指定されます

オペレーティングシステムがファイルが存在する場合はそれを開く必要があること。それ以外の場合は、新しいファイルを作成する必要があります。

したがって、指定された場所にすでにファイルがある場合、そのファイルは残り、書き込みを開始します。

作成する新しいファイルが古いファイルよりも長い場合、これは問題ありません。最終的にすべての古いファイルコンテンツを上書きすると、ファイルは拡大して追加の新しいコンテンツを格納します。

ただし、作成する新しいファイルが古いファイルよりも短い場合は、問題が発生します。新しいファイルの終了後も、古い長いファイルのデータが残っています。したがって、結果は2つのファイルの寄せ集めになります。

これは、共有したサンプルファイルの場合に発生しました。「signedPdf.pdf」の新しいコンテンツの長さはわずか175982バイトですが、その名前の古いファイルが811986バイトの長さであったようです。したがって、共有した「signedPdf.pdf」ファイルの長さは811986バイトで、最初の175982バイトには操作の結果が含まれ、残りのデータには他のファイルのデータが含まれます。

共有の「signedPdf.pdf」ファイルを最初の175982バイトに削減すると、結果ははるかに良くなります。

この問題を解決するにCreateは、次のように文書化されているファイルモードを使用する必要があります

ファイルが存在しない場合は、CreateNew;を使用するように要求するのと同じです。それ以外の場合は、を使用しますTruncate

using (FileStream os = new FileStream(signedPdf, FileMode.Create, FileAccess.Write, FileShare.None))

署名サービスの問題-IDはまだ有効ではありません

上記のように、共有の「signedPdf.pdf」ファイルを最初の175982バイトに削減すると、結果ははるかに良くなります。残念ながら、単に良く、まだ良くありません:

「IDの有効期限が切れているか、まだ有効ではない」理由は、詳細を確認することで明らかになります。

つまり、PDFで要求されている署名時間は09:47:59 UTC +1です。

しかし、証明書を見ると:

つまり、証明書は09:48:40 UTC +1より前では有効ではありません。

したがって、要求された署名時間は、ユーザー証明書が有効になるまでに30分以上かかります。これは明らかにバリデーターによって受け入れられません...

どうやらあなたの署名サービスはオンデマンドであなたのために短時間の証明書を作成し、その時から30分の間有効です。また、PDF署名の作成を開始した時刻、その間隔ではありません

彼らがあなたの要求に合わせて署名サービスのデザインを変えるとは思えません。したがって、将来的には少しごまかして署名時間を少し使用する必要があります。

デフォルトでは、署名時間はPdfSignatureAppearanceコンストラクターによって現在に設定されます。つまり、この行が実行されるときです。

PdfSignatureAppearance appearance = stamper.SignatureAppearance;

幸い、すぐに使用すれば、この主張された署名時間を変更できます

appearance.SignDate = [some other date time];

ここで使用する必要のある日時は、署名サービスに電話をかける時刻の直後(5分以内を提案します)でなければなりません。

もちろん、これは、そのサービス呼び出しが実行されるまで任意に待つことができないことを意味します。上記の請求された署名時間を割り当てるとすぐに、その請求された時間の直前に署名サービスに正常に電話をかけることになります。

さらに、その署名サービスの反応が遅いか、再試行後にのみ反応することが判明した場合、ソフトウェアは、そこから取得した署名コンテナ内の証明書を確実にチェックし、その有効期間を要求された署名時間と比較する必要があります。要求された署名時間がその間隔内にない場合は、再度署名を開始してください。


これで、AllPagesSignatureContainer使用したものが非常に特殊なユースケース向けに設計されていて、それでもユースケースに適合させる必要があることが明らかになりました。

AllPagesSignatureContainer追加モードへの適応

AllPagesSignatureContainer基本的にからコピーされた実装で、この答えは、追加モードでの署名が、追加モードで署名するとき、それは失敗していない時に罰金を働きました。

そのクラスは署名値に使用されるオブジェクト番号を予測する必要があるため、これは最初はもっともらしいものでした。この予測は正確なユースケースに依存し、追加モードをオンにすると、このユースケースが大幅に変わります。したがって、コメントでの私のアドバイスは

追加モードが必要な場合は、

PdfLiteral PRefLiteral = ...

AllPagesSignatureContainerによっての行

PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + reader.NumberOfPages) + " 0 R");

私のテストでは機能しましたが、あなたのテストではまだ機能しませんでした。署名されたファイルを分析したところ、原因が判明しました。テストファイルは相互参照テーブルを使用していましたが、相互参照ストリームを使用していました。

適応AllPagesSignatureContainer追加モードとオブジェクトストリームのために

追加モードのiTextは、元のファイルの圧縮機能を使用します。つまり、ファイルの場合、オブジェクトストリームに保存できる間接オブジェクトを保存するとすぐに、オブジェクトストリームが作成されます。

ファイルの場合、iTextはオブジェクトストリーム用にオブジェクト番号を予約しました。これはAllPagesSignatureContainer、署名値のオブジェクト番号が予測されてから実際に署名値が生成されるまでの間に行われました。したがって、ファイルでは、実際の署名値オブジェクト番号が予測番号より1大きくなりました。

したがって、相互参照ストリームを含むPDFでこれを解決するには、PdfLiteral PRefLiteral = ...行を次のように置き換えるだけです。

PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + reader.NumberOfPages + 1) + " 0 R");

つまり、最初に予測された値に1を加算します。残念ながら、相互参照テーブルのあるPDFの予測は間違っています...

これを修正するより良い方法は、署名値のオブジェクト番号を予測する前に、相互参照ストリームPDF用にオブジェクトストリームのオブジェクト番号をiTextに予約させてから、元の予測コードを使用することです。これを行う1つの方法は、予測の直前に間接オブジェクトを作成して書き込むことです。たとえば、次のようになります。

stamper.Writer.AddToBody(new PdfNull(), stamper.Writer.PdfIndirectReference, true);

PdfIndirectReference PRef = stamper.Writer.PdfIndirectReference;
PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + reader.NumberOfPages) + " 0 R");

AllPagesSignatureContainer実装が本質的にコピーされた回答は、それに応じて更新されました。

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

今週のコミックコンですべての素晴らしいものに追いつく方法

今週のコミックコンですべての素晴らしいものに追いつく方法

サンディエゴコミックコンは今週開幕し、オタクのアナウンス、ポスター、予告編、お気に入りの番組や映画のからかいでいっぱいになります。SDCCは、コンベンションフロア全体の多くのパネルで行われているため、すべてに対応するのは難しい場合があります。

Googleの9千万ドルの和解はアプリ開発者にとってもGoogleにとっても勝利ですか?

Googleの9千万ドルの和解はアプリ開発者にとってもGoogleにとっても勝利ですか?

小さなアプリ開発者は金曜日に発表された法的な和解でグーグルから9千万ドルをこじ開けた。アップルとの同様の合意に続いて熱くなった。金曜日のブログ投稿で、Googleは、Androidメーカーが市場での優位性を悪用してPlayストア経由でのアプリ内購入に対して30%の料金を不当に請求したと主張するアプリ開発者との訴訟を解決するために、9千万ドルを支払うことに合意したと述べました。

RadioShackのTwitterはハッキングされていませんでした、それはただの暗号のサクラです

RadioShackのTwitterはハッキングされていませんでした、それはただの暗号のサクラです

今週、RadioShackのTwitterアカウントは、奇妙なものから完全にひどいものになりました。短い順序で、会社のフィード全体が、バイブレーター、「ビッグティット」(スペルミス)、有名人やその他の企業アカウントを荒らしているツイートなど、NSFW素材の真の山になりました。

ヒッグス粒子から10年後、物理学にとって次の大きなものは何ですか?

ヒッグス粒子から10年後、物理学にとって次の大きなものは何ですか?

大型ハドロン衝突型加速器のトンネル内にあるコンパクトミュオンソレノイド(CMS)検出器。2012年7月4日、CERNの科学者たちは、1960年代に最初に提案された素粒子であるヒッグス粒子の観測を確認しました。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

Seguindo Todos os Protocolos (2022), de Fábio Leal

Seguindo Todos os Protocolos (2022), de Fábio Leal

Chico quer transar. Até aí, tudo bem.

多元宇宙—Junø

多元宇宙—Junø

チェーン間アカウントがJunoに登場します。異なるブロックチェーン間でスマートコントラクトの構成可能性と真の相互運用性を提供します。

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

1.ドラマを見た後、起業する考えはありますか?あなたのビジネスはボトルネックに遭遇しましたか?方向性がなくてわからない場合は、ドラマを追いかけて行くことを心からお勧めします。(?)ブラフではなく、最も完璧なビジネス例を隠すドラマがあります。2.ブレイキング・バッドとその弁護士ドラマ「ブレイキング・バッド」を見た友人たちは、演劇の中で、穏やかな表情で、弁護士のソウル・グッドマンに深く感銘を受けなければなりません。口を開けて、感覚の弱い傭兵の性格を持っています。道徳の面で、サル・グッドマンは無意識のうちに劇に欠かせない役割を果たし、彼自身のシリーズ「絶望的な弁護士」(ベター・コール・ソール)を生み出しました。ウェントウのテキストとビデオは、劇中のソウル・グッドマンのテレビコマーシャルです。製品(サービス)、競争戦略、市場ポジショニング、ブランド名、ターゲット顧客グループ、コミュニケーション軸から広告まで、サル・グッドマンの役割のビジネス設定は、「最低」と見なすことができる超超超超超超完全です。ブランドコミュニケーションのコスト」「変化」のモデル。なぜ?私の分析をご覧ください。3.ソウル・グッドマンの「事業戦略」1.基本情報ブランド名:Saul Goodman製品:法律相談サービス対象顧客:麻薬中毒、飲酒運転、事故など。法律知識の欠如は、一般的に公立弁護士にしか余裕がなく、真面目な弁護士も「特別な法律を持つ消費者」を避けます。恐れてはいけない「​​ニーズ」。コミュニケーションの主軸:この国のすべての男性、女性、子供は有罪判決を受けるまで無実だと思います。地域:アルバカーキ市スローガン:Thrallに電話したほうがいいです!(ベター・コール・ソール)広告:2つの可能性のある犯罪状況をシミュレートします+サウルの主張+サウルのスローガン2をより適切に呼び出します。

メインネットガイド— Arbitrum Odyssey Week 2

メインネットガイド— Arbitrum Odyssey Week 2

最新のアップデートを受け取るために私たちに従ってください。ニュースレター:https://www。

Language