블로그 이미지
래머
오늘도 열심히 개발하는 개발자입니다.

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

2015. 9. 13. 07:04 c#

네이버의 경우 구글과 같은 형태로 영수증을 발급하고 있습니다.

그렇기 때문에 구글 결제모듈과 동일한 방법으로 영수증 검증을 하면되는데 차이점은

네이버결제 데이터에는 한글같은게 포함되기 때문에 약간의 수정이 있어야 합니다.


아래 코드는 네이버 결제 코드 검증 루틴의 코드입니다.


구글 검증루틴과 차이점은 아래 코드에서 진하게 표시해놓은(Encoding.UTF8.GetBytes(Message)) 부분입니다.


바운시 캐슬 암호화 루틴은 구글 결제 코드 예제에 보시면 포함되어 있고, 라이브러리를 포함하기 힘든경우에는

바운시 캐슬 사이트에서 소스 코드를 직접 받아서 사용하시면됩니다.

http://www.bouncycastle.org/


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using System.Security.Cryptography;
using System;
public class NaverSignatureVerify
    {
        RSAParameters _rsaKeyInfo;
 
        public NaverSignatureVerify(String strNaverPublicKey)
        {
            RsaKeyParameters rsaParameters = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(strNaverPublicKey));
 
            byte[] rsaExp = rsaParameters.Exponent.ToByteArray();
            byte[] Modulus = rsaParameters.Modulus.ToByteArray();
 
            // Microsoft RSAParameters modulo wants leading zero's removed so create new array with leading zero's removed
            int Pos = 0;
            for (int i = 0; i < Modulus.Length; i++)
            {
                if (Modulus[i] == 0)
                {
                    Pos++;
                }
                else
                {
                    break;
                }
            }
            byte[] rsaMod = new byte[Modulus.Length - Pos];
            Array.Copy(Modulus, Pos, rsaMod, 0, Modulus.Length - Pos);
 
            // Fill the Microsoft parameters
            _rsaKeyInfo = new RSAParameters()
            {
                Exponent = rsaExp,
                Modulus = rsaMod
            };
        }
 
        public bool Verify(String Message, String Signature)
        {
            if (Application.platform == RuntimePlatform.Android)
            {
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                {
                    try
                    {
                        rsa.ImportParameters(_rsaKeyInfo);
                        return rsa.VerifyData(Encoding.UTF8.GetBytes(Message)"SHA1", Convert.FromBase64String(Signature));
                    }
                    catch (System.Exception ex)
                    {
#if NEED_LOG
                        Debug.Log("Verify failed : " + ex.ToString());
#endif
                        return false;
                    }
 
                }
            }
            else
            {
                return true;
            }
        }
    }
cs


'c#' 카테고리의 다른 글

c#에서 자바의 ByteBuffer 구현하기  (0) 2014.05.05
심플 타임체커  (0) 2014.05.04
c# web safe base64  (0) 2014.05.02
posted by 래머
2014. 5. 5. 01:23 c#

자바의 경우 기본자료형들을 직렬화 및 역직렬화 하기위한 ByteBuffer라는 클래스를 제공해준다.

c#의 경우에도 비슷한역할을 하는 클래스가 있는데

아무튼 자바의 바이트 버퍼와 처림 구현해볼 수 있다.


기본 자료형의 경우 BitConverter 클래스를 통해서 직렬화 및 역직렬화가 가능하다.


아래의 클래스는 자바의 바이트 버퍼를 구현해 놓은 것으로 사용법도 거의 유사하다.


using System;

using System.Collections.Generic;

using System.Text;


namespace G_UTIL

{

    /// <summary>

    /// 기본 데이터타입의 바이트 생성 유틸리티

    /// </summary>

    public class ByteBuffer

    {

        public const int SIZE_UINT = 4;

        public const int SIZE_INT = 4;

        public const int SIZE_LONG = 8;

        public const int SIZE_BYTE = 1;

        public const int SIZE_SHORT = 2;

        public const int SIZE_FLOAT = 4;

        public const int SIZE_DOUBLE = 8;

        public const int SIZE_BOOL = 1;


        private int m_iPos;

        private int m_iMax;

        byte[] m_Buf;


        public void ClearBuf()

        {

            m_iPos = 0;

            m_iMax = 0;

            m_Buf = null;

        }


        public ByteBuffer()

        {

            m_iPos = 0;

            m_iMax = 0;

            m_Buf = null;

        }


        public ByteBuffer(byte[] arr)

        {

            m_iPos = 0;


            if (arr != null)

                m_iMax = arr.Length;

            else

                m_iMax = 0;


            m_Buf = arr;

        }


        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="iLimit">내부 배열 최대 크기</param>

        public ByteBuffer(int iLimit)

        {

            m_iPos = 0;

            m_iMax = iLimit;

            m_Buf = new byte[iLimit];

        }


        /// <summary>

        /// 주어진 크기로 객체 할당

        /// </summary>

        /// <param name="iSize">제한 크기</param>

        /// <returns></returns>

        public static ByteBuffer allocate(int iSize)

        {

            return new ByteBuffer(iSize);

        }

        

        /// <summary>

        /// 내부 배열 객체 얻기

        /// </summary>

        /// <returns></returns>

        public byte[] array() { return m_Buf; }


        /// <summary>

        /// 커서를 처음 위치로 이동시킴

        /// </summary>

        public void rewind() { m_iPos = 0; }



        /// <summary>

        /// 현재 커서 위치 얻기

        /// </summary>

        /// <returns></returns>

        public int position() { return m_iPos; }


        /// <summary>

        /// 최대 용량 정보 얻기

        /// </summary>

        /// <returns></returns>

        public int capacity() { return m_iMax; }


        public bool IsValid() { return m_iPos < m_iMax ? true : false; }

        /// <summary>

        /// 커서를 지정된 만큼 이동시킴

        /// </summary>

        /// <param name="s"></param>

        public bool MovePos(int s)

        {

            int old = m_iPos;


            m_iPos += s;


            if (m_iPos < 0 || m_iPos >= m_iMax)

            {

                m_iPos = old;

                return false;

            }


            return true;

        }


        public bool SetPos(int s)

        {

            if (s < 0 || s >= m_iMax)

                return false;


            m_iPos = s;

            return true;

        }


        /// <summary>

        /// 바이트 값 추가, 커서는 바이트 크기 만큼 전진

        /// </summary>

        /// <param name="data"></param>

        public void put(byte data)

        {

            if ((m_iPos+1) > m_iMax)

                return;

            m_Buf[m_iPos++] = data;

        }



        /// <summary>

        /// 바이트 배열 복사, 커서는 바이트 배열의 크기만큼 전진함

        /// </summary>

        /// <param name="data">바이트 배열</param>

        public void put(byte[] data)

        {

            if (data == null || (m_iPos + data.Length) > m_iMax)

                return;


            Array.Copy(data, 0, m_Buf, m_iPos, data.Length);


            m_iPos += data.Length;

        }



        /// <summary>

        /// 바이트 배열 복사, 커서는 바이트 배열의 크기만큼 전진함

        /// </summary>

        /// <param name="data">복사할 배열</param>

        /// <param name="iOffset">복사 시작점</param>

        /// <param name="iLen">복사길이 바이트</param>

        public void put(byte[] data, int iOffset, int iLen)

        {

            if ((m_iPos + iLen) > m_iMax)

                return;

            

            Array.Copy(data, iOffset, m_Buf, m_iPos, iLen);

            m_iPos += iLen;

        }



        /// <summary>

        /// short 데이터 추가, 커서는 short 길이 만큼 전진(2바이트)

        /// </summary>

        /// <param name="s">값</param>

        public void putShort(short s)

        {

            if ((m_iPos + 2) > m_iMax)

                return;


            byte[] buf = new byte[2];


            buf = BitConverter.GetBytes(s);




            m_Buf[m_iPos++] = buf[0];


            m_Buf[m_iPos++] = buf[1];


        }



        /// <summary>

        /// unsigned short 데이터 추가, 커서는 unsigned short 길이 만큼 전진(2바이트)

        /// </summary>

        /// <param name="s"></param>

        public void putUShort(ushort s)

        {

            if ((m_iPos + 2) > m_iMax)

                return;


            byte[] buf = new byte[2];


            buf = BitConverter.GetBytes(s);


            m_Buf[m_iPos++] = buf[0];

            m_Buf[m_iPos++] = buf[1];

        }



        /// <summary>

        /// int 값 추가 : 커서는 int 길이만큼 전진(4바이트)

        /// </summary>

        /// <param name="s">값</param>

        public void putInt(int s)

        {

            if ((m_iPos + 4) > m_iMax)

                return;


            byte[] buf = new byte[4];


            buf = BitConverter.GetBytes(s);


            m_Buf[m_iPos++] = buf[0];

            m_Buf[m_iPos++] = buf[1];

            m_Buf[m_iPos++] = buf[2];

            m_Buf[m_iPos++] = buf[3];

        }


        /// <summary>

        /// unsigned int 값 추가, 커서는 unsigned int 길이만큼전진(4바이트)

        /// </summary>

        /// <param name="s">값</param>

        public void putUInt(uint s)

        {

            if ((m_iPos + 4) > m_iMax)

                return;

            byte[] buf = new byte[4];


            buf = BitConverter.GetBytes(s);


            m_Buf[m_iPos++] = buf[0];

            m_Buf[m_iPos++] = buf[1];

            m_Buf[m_iPos++] = buf[2];

            m_Buf[m_iPos++] = buf[3];

        }



        /// <summary>

        /// long 값 추가 : 커서는 long길이 만큼전진(8바이트)

        /// </summary>

        /// <param name="s">값</param>

        public void putLong(long s)

        {

            if ((m_iPos + 8) > m_iMax)

                return;

            byte[] buf = new byte[8];


            buf = BitConverter.GetBytes(s);


            m_Buf[m_iPos++] = buf[0];

            m_Buf[m_iPos++] = buf[1];

            m_Buf[m_iPos++] = buf[2];

            m_Buf[m_iPos++] = buf[3];

            m_Buf[m_iPos++] = buf[4];

            m_Buf[m_iPos++] = buf[5];

            m_Buf[m_iPos++] = buf[6];

            m_Buf[m_iPos++] = buf[7];

        }

        

        /// <summary>

        /// long 값 추가 : 커서는 long길이 만큼전진(8바이트)

        /// </summary>

        /// <param name="s">값</param>

        public void putLongWithKey(long s, byte btKey)

        {

            if ((m_iPos + 8) > m_iMax)

                return;

            byte[] buf = new byte[8];


            buf = BitConverter.GetBytes(s);


            m_Buf[m_iPos++] = (byte)(buf[0] ^ btKey);

            m_Buf[m_iPos++] = (byte)(buf[1] ^ btKey);

            m_Buf[m_iPos++] = (byte)(buf[2] ^ btKey);

            m_Buf[m_iPos++] = (byte)(buf[3] ^ btKey);

            m_Buf[m_iPos++] = (byte)(buf[4] ^ btKey);

            m_Buf[m_iPos++] = (byte)(buf[5] ^ btKey);

            m_Buf[m_iPos++] = (byte)(buf[6] ^ btKey);

            m_Buf[m_iPos++] = (byte)(buf[7] ^ btKey);

        }


        /// <summary>

        /// float 값 추가 : 커서는 float길이 만큼 전진(4바이트)

        /// </summary>

        /// <param name="s">값</param>

        public void putFloat(float s)

        {

            if ((m_iPos + 4) > m_iMax)

                return;


            byte[] buf = new byte[4];


            buf = BitConverter.GetBytes(s);


            m_Buf[m_iPos++] = buf[0];

            m_Buf[m_iPos++] = buf[1];

            m_Buf[m_iPos++] = buf[2];

            m_Buf[m_iPos++] = buf[3];

        }



        /// <summary>

        /// double값 추가 : 커서는 double 길이 만큼 전진(8바이트)

        /// </summary>

        /// <param name="s"></param>

        public void putDouble(double s)

        {

            if ((m_iPos + 8) > m_iMax)

                return;


            byte[] buf = new byte[8];


            buf = BitConverter.GetBytes(s);


            m_Buf[m_iPos++] = buf[0];

            m_Buf[m_iPos++] = buf[1];

            m_Buf[m_iPos++] = buf[2];

            m_Buf[m_iPos++] = buf[3];

            m_Buf[m_iPos++] = buf[4];

            m_Buf[m_iPos++] = buf[5];

            m_Buf[m_iPos++] = buf[6];

            m_Buf[m_iPos++] = buf[7];

        }



        /// <summary>

        /// 현재 커서 위치로 부터 1바이트값 얻어옴 : 커서는 +1바이트 전진

        /// </summary>

        /// <returns></returns>

        public byte GetByte()

        {

            if ((m_iPos + 1) > m_iMax)

                return 0;


            return m_Buf[m_iPos++];

        }


        /// <summary>

        /// 현재 커서 위치로 부터 short값 얻어옴 : 커서는 +2바이트 전진

        /// </summary>

        /// <returns></returns>

        public short getShort()

        {

            if ((m_iPos + 2) > m_iMax)

                return 0;


            m_iPos += 2;


            return BitConverter.ToInt16(m_Buf, m_iPos - 2);


        }



        /// <summary>

        /// 현재 커서 위치로 부터 ushort값 얻어옴 : 커서는 +2바이트 전진

        /// </summary>

        /// <returns></returns>

        public ushort getUShort()

        {

            if ((m_iPos + 2) > m_iMax)

                return 0;


            m_iPos += 2;


            return BitConverter.ToUInt16(m_Buf, m_iPos - 2);


        }



        /// <summary>

        /// 현재 커서 위치로 부터 int값 얻어옴 : 커서는 +4바이트 전진

        /// </summary>

        /// <returns></returns>

        public int getInt()

        {

            if ((m_iPos + 4) > m_iMax)

                return 0;


            m_iPos += 4;


            return BitConverter.ToInt32(m_Buf, m_iPos - 4);


        }


        /// <summary>

        /// 현재 커서 위치로 부터 uint값 얻어옴 : 커서는 +4바이트 전진

        /// </summary>

        /// <returns></returns>

        public uint getUInt32()

        {

            if ((m_iPos + 4) > m_iMax)

                return 0;


            m_iPos += 4;


            return BitConverter.ToUInt32(m_Buf, m_iPos - 4);


        }



        /// <summary>

        /// 현재 커서 위치로 부터 float값 얻어옴 : 커서는 +4바이트 전진

        /// </summary>

        /// <returns></returns>

        public float getFloat()

        {

            if ((m_iPos + 4) > m_iMax)

                return 0;


            m_iPos += 4;


            return BitConverter.ToSingle(m_Buf, m_iPos - 4);


        }



        /// <summary>

        /// 현재 커서 위치로 부터 double값 얻어옴 : 커서는 +8바이트 전진

        /// </summary>

        /// <returns></returns>

        public double getDouble()

        {

            if ((m_iPos + 8) > m_iMax)

                return 0;


            m_iPos += 8;


            return BitConverter.ToDouble(m_Buf, m_iPos - 8);


        }



        /// <summary>

        /// 현재 커서 위치로 부터 long값 얻어옴 : 커서는 +8바이트 전진

        /// </summary>

        /// <returns></returns>

        public long getLong()

        {

            if ((m_iPos + 8) > m_iMax)

                return 0;


            m_iPos += 8;


            return BitConverter.ToInt64(m_Buf, m_iPos - 8);

        }


        /// <summary>

        /// 현재 커서 위치로 부터 long값 얻어옴 : 커서는 +8바이트 전진

        /// </summary>

        /// <returns></returns>

        public long getLongWithKey(byte btKey)

        {

            if ((m_iPos + 8) > m_iMax)

                return 0;


            try

            {

                byte[] arr = new byte[SIZE_LONG];


                arr[0] = (byte)(m_Buf[m_iPos++] ^ btKey);

                arr[1] = (byte)(m_Buf[m_iPos++] ^ btKey);

                arr[2] = (byte)(m_Buf[m_iPos++] ^ btKey);

                arr[3] = (byte)(m_Buf[m_iPos++] ^ btKey);

                arr[4] = (byte)(m_Buf[m_iPos++] ^ btKey);

                arr[5] = (byte)(m_Buf[m_iPos++] ^ btKey);

                arr[6] = (byte)(m_Buf[m_iPos++] ^ btKey);

                arr[7] = (byte)(m_Buf[m_iPos++] ^ btKey);

                return BitConverter.ToInt64(arr, 0);

            }

#if KAKAO_TEST_MODE

            catch (Exception e)

            {

                Debug.Log(e.ToString());

#else

            catch

            {

#endif

                return 0;

            }

        }


        /// <summary>

        /// 주어진 바이트 배열에 주어진 길이 만큼, 데이터 복사, 커서는 길이만큼 전진

        /// </summary>

        /// <param name="buf">복사 대상 버퍼</param>

        /// <param name="len">복사할길이</param>

        /// <returns>복사된 버퍼</returns>

        public byte[] GetBytes(byte[] buf, int len)

        {

            if ((m_iPos + len) > m_iMax)

                return buf;


            Array.Copy(m_Buf, m_iPos, buf, 0, len);


            m_iPos += len;


            return buf;

        }


        public void putBool(bool v)

        {

            put(v ? (byte)1 : (byte)0);

        }


        public bool getBool()

        {

            if (GetByte() == 1)

                return true;


            return false;

        }

    }

}





'c#' 카테고리의 다른 글

네이버 앱스토어 인앱영수증 검증 c#버전  (0) 2015.09.13
심플 타임체커  (0) 2014.05.04
c# web safe base64  (0) 2014.05.02
posted by 래머
2014. 5. 4. 00:05 c#

class CMyTime

    {

        private long m_lOld = DateTime.Now.Ticks;


//현재 시간 캡쳐

        public void Catch()

        {

            m_lOld = DateTime.Now.Ticks;

        }


//마지막으로 시간을 캡쳐한 때로 부터 이 함수를 호출할때까지 경과한 시간을 틱단위로 얻음

        public long GetPassedTime()

        {

            return (DateTime.Now.Ticks - m_lOld);

        }


//마지막으로 시간을 캡쳐한 때로 부터 이 함수를 호출할때까지 경과한 시간을 초단로 얻음

        public float GetSecond()

        {

            return (float)((DateTime.Now.Ticks - m_lOld) * 0.0000001f);

        }


//해당 틱이 몇초에 해당하는 지

        static public float ToSecond(long lTick)

        {

            return ((float)(lTick) * 0.0000001f);

        }


        /// <summary>

        /// 현재의 요일 정보 얻기

        /// </summary>

        /// <returns></returns>

        public static DayOfWeek GetDayofWeek()

        {

            return DateTime.Now.DayOfWeek;

        }

    }




'c#' 카테고리의 다른 글

네이버 앱스토어 인앱영수증 검증 c#버전  (0) 2015.09.13
c#에서 자바의 ByteBuffer 구현하기  (0) 2014.05.05
c# web safe base64  (0) 2014.05.02
posted by 래머
2014. 5. 2. 00:53 c#



c# web safe base64

기본적으로 c#의 base64로 변환후 스트링의 Replace기능을 이용해서
+는 -로 /는 _로 변환하면된다.

string strInput = "base64로 바꿀 문자열";



string strWebSafeBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(strInput)).Replace('+', '-').Replace('/', '_');




'c#' 카테고리의 다른 글

네이버 앱스토어 인앱영수증 검증 c#버전  (0) 2015.09.13
c#에서 자바의 ByteBuffer 구현하기  (0) 2014.05.05
심플 타임체커  (0) 2014.05.04
posted by 래머
prev 1 next